Перш ніж продовжувати цю публікацію, важливо зрозуміти різницю між NaN та None . Один - тип плаваючого, інший - об’єктного типу. Pandas краще підходить для роботи зі скалярними типами, оскільки багато методів для цих типів можна векторизувати. Панди намагаються послідовно обробляти None та NaN, але NumPy не може.
Моя пропозиція ( і Енді ) - дотримуватися NaN.
Але щоб відповісти на ваше запитання ...
pandas> = 0,18: Використовуйте na_values=['-']
аргумент зread_csv
Якщо ви завантажили ці дані з CSV / Excel, я маю для вас хороші новини. Ви можете скасувати це в корені під час завантаження даних, замість того, щоб писати виправлення з кодом як наступний крок.
Більшість pd.read_*
функцій (таких як read_csv
і read_excel
) приймають na_values
атрибут.
file.csv
A,B
-,1
3,-
2,-
5,3
1,-2
-5,4
-1,-1
-,0
9,0
Тепер, щоб перетворити -
символи в NaN, зробіть,
import pandas as pd
df = pd.read_csv('file.csv', na_values=['-'])
df
A B
0 NaN 1.0
1 3.0 NaN
2 2.0 NaN
3 5.0 3.0
4 1.0 -2.0
5 -5.0 4.0
6 -1.0 -1.0
7 NaN 0.0
8 9.0 0.0
І подібне для інших функцій / форматів файлів.
PS: На v0.24 + ви можете зберегти цілочисельний тип, навіть якщо у вашій колонці є NaN (так, поговоримо про те, щоб мати пиріг і з'їсти його теж). Ви можете вказатиdtype='Int32'
df = pd.read_csv('file.csv', na_values=['-'], dtype='Int32')
df
A B
0 NaN 1
1 3 NaN
2 2 NaN
3 5 3
4 1 -2
5 -5 4
6 -1 -1
7 NaN 0
8 9 0
df.dtypes
A Int32
B Int32
dtype: object
Dtype не є звичайним типом int ..., а навпаки, Nullable Integer Type. Є й інші варіанти.
Обробка числових даних: pd.to_numeric
сerrors='coerce
Якщо ви маєте справу з числовими даними, швидшим рішенням є використання pd.to_numeric
з errors='coerce'
аргументом, який примушує до NaN недійсні значення (значення, які неможливо передати числовим).
pd.to_numeric(df['A'], errors='coerce')
0 NaN
1 3.0
2 2.0
3 5.0
4 1.0
5 -5.0
6 -1.0
7 NaN
8 9.0
Name: A, dtype: float64
Щоб зберегти (з нульовим значенням) ціле число dtype, використовуйте
pd.to_numeric(df['A'], errors='coerce').astype('Int32')
0 NaN
1 3
2 2
3 5
4 1
5 -5
6 -1
7 NaN
8 9
Name: A, dtype: Int32
Щоб примусити кілька стовпців, використовуйте apply
:
df[['A', 'B']].apply(pd.to_numeric, errors='coerce').astype('Int32')
A B
0 NaN 1
1 3 NaN
2 2 NaN
3 5 3
4 1 -2
5 -5 4
6 -1 -1
7 NaN 0
8 9 0
... і призначити результат назад після.
Більше інформації можна знайти в цій відповіді .
write_frame
не розбираєNaN
s наnone
s?