簡體   English   中英

在 pandas 中查找 dataframe 中的非數字行?

[英]Finding non-numeric rows in dataframe in pandas?

我在 pandas 中有一個大的 dataframe,除了用作索引的列應該只有數值:

df = pd.DataFrame({'a': [1, 2, 3, 'bad', 5],
                   'b': [0.1, 0.2, 0.3, 0.4, 0.5],
                   'item': ['a', 'b', 'c', 'd', 'e']})
df = df.set_index('item')

如何找到 dataframe df中包含非數字值的行?

在此示例中,它是 dataframe 中的第四行,其a列中包含字符串'bad' 如何以編程方式找到這一行?

您可以使用np.isreal檢查每個元素的類型( applymap將一個函數應用於DataFrame中的每個元素):

In [11]: df.applymap(np.isreal)
Out[11]:
          a     b
item
a      True  True
b      True  True
c      True  True
d     False  True
e      True  True

如果該行中的所有均為True,則它們都是數字:

In [12]: df.applymap(np.isreal).all(1)
Out[12]:
item
a        True
b        True
c        True
d       False
e        True
dtype: bool

因此,要獲得路由的subDataFrame,(請注意:上面的否定〜會找到至少具有一個非流氓非數字字符的那些):

In [13]: df[~df.applymap(np.isreal).all(1)]
Out[13]:
        a    b
item
d     bad  0.4

您還可以找到可以使用argmin第一個罪犯的位置:

In [14]: np.argmin(df.applymap(np.isreal).all(1))
Out[14]: 'd'

正如@CTZhu指出的那樣, 檢查它是int還是float 的實例可能會稍快一些(np.isreal會有一些額外的開銷):

df.applymap(lambda x: isinstance(x, (int, float)))

對於這個問題已經有了一些不錯的答案,但是如果有行在某些列上使用非數字值,我會定期使用它來刪除行:

# Eliminate invalid data from dataframe (see Example below for more context)

num_df = (df.drop(data_columns, axis=1)
         .join(df[data_columns].apply(pd.to_numeric, errors='coerce')))

num_df = num_df[num_df[data_columns].notnull().all(axis=1)]

該方法這是工作,我們首先drop所有data_columnsdf ,然后用join到將它們放回使它們通過后pd.to_numeric (與選項'coerce' ,這樣所有非數字輸入轉換為NaN )。 結果保存到num_df

在第二行中,我們使用一個過濾器,該過濾器僅保留所有值都不為null的行。

請注意, pd.to_numeric將所有無法轉換為數字值的內容強制轉換為NaN ,因此不會刪除表示數字值的字符串。 例如, '1.25'將被識別為數值1.25

免責聲明: pd.to_numeric在pandas版本0.17.0引入

例:

In [1]: import pandas as pd

In [2]: df = pd.DataFrame({"item": ["a", "b", "c", "d", "e"],
   ...:                    "a": [1,2,3,"bad",5],
   ...:                    "b":[0.1,0.2,0.3,0.4,0.5]})

In [3]: df
Out[3]: 
     a    b item
0    1  0.1    a
1    2  0.2    b
2    3  0.3    c
3  bad  0.4    d
4    5  0.5    e

In [4]: data_columns = ['a', 'b']

In [5]: num_df = (df
   ...:           .drop(data_columns, axis=1)
   ...:           .join(df[data_columns].apply(pd.to_numeric, errors='coerce')))

In [6]: num_df
Out[6]: 
  item   a    b
0    a   1  0.1
1    b   2  0.2
2    c   3  0.3
3    d NaN  0.4
4    e   5  0.5

In [7]: num_df[num_df[data_columns].notnull().all(axis=1)]
Out[7]: 
  item  a    b
0    a  1  0.1
1    b  2  0.2
2    c  3  0.3
4    e  5  0.5

抱歉,這是正確的方法。 您是否只想捕捉'bad' ,而不是'good' 還是只是任何非數字值?

In[15]:
np.where(np.any(np.isnan(df.convert_objects(convert_numeric=True)), axis=1))
Out[15]:
(array([3]),)
# Original code
df = pd.DataFrame({'a': [1, 2, 3, 'bad', 5],
                   'b': [0.1, 0.2, 0.3, 0.4, 0.5],
                   'item': ['a', 'b', 'c', 'd', 'e']})
df = df.set_index('item')

使用'coerce' 轉換為數值,並用'nan'填充錯誤值

a = pd.to_numeric(df.a, errors='coerce')

使用isna返回布爾值索引:

idx = a.isna()

將該索引應用於數據框:

df[idx]

輸出

返回其中包含錯誤數據的行:

        a    b
item          
d     bad  0.4

如果您正在使用帶有字符串值的列,則可以使用非常有用的函數series.str.isnumeric(),例如:

a = pd.Series(['hi','hola','2.31','288','312','1312', '0,21', '0.23'])

我要做的是將該列復制到新列,並執行str.replace('。','')和str.replace(',',''),然后選擇數值。 和:

a = a.str.replace('.','')
a = a.str.replace(',','') 
a.str.isnumeric()

Out [15]:0錯誤1錯誤2對3對4對5對6對6對7對dtype:bool

祝你好運!

我在想類似的東西,只是給出一個想法,即可將列轉換為字符串,並且使用字符串更容易。 但是,這不適用於包含數字的字符串,例如bad123 ~是選擇的補充。

df['a'] = df['a'].astype(str)
df[~df['a'].str.contains('0|1|2|3|4|5|6|7|8|9')]
df['a'] = df['a'].astype(object)

並使用'|'.join([str(i) for i in range(10)])生成'0|1|...|8|9'

或使用np.isreal()函數,就像投票最多的答案一樣

df[~df['a'].apply(lambda x: np.isreal(x))]

您是否使用 .astype() 轉換了數據?

以上所有精彩評論一定能解決 99% 的情況,但如果您仍然遇到問題,請同時檢查您是否轉換了數據類型。

有時我強制數據鍵入 float16 以保存 memory。使用:

df[col] = df[col].astype(np.float16)

但這可能會悄悄地破壞你的代碼。 因此,如果您進行了任何類型的數據類型轉換,請仔細檢查是否存在溢出 禁用轉換並重試。

它對我有用!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM