寻找更快的方法从熊猫数据框中删除所有占位符

时间:2018-08-08 17:20:04

标签: python performance pandas

我从其他人那里收到了很多充满数据的.CSV和excel文件,它们总是用随机占位符(如N / a等)填充空白字段。我编写了一个函数来遍历一列并删除一个该数据集中的这些占位符的列表。如果问题影响了整个数据集,我甚至可以遍历所有列并从整个数据集中清除占位符。问题在于,迭代每个列和行以及可能的占位符非常慢。我希望有人可以告诉我更快或更简单的方式来完成此任务。谢谢!

我当前的功能:

def drop_placeholders(dataframe, column, placeholder_list=['N/A', 'N/a', 'n/a', 'NaN', 'none', '<none>', 'Unassigned', 'Not Reported', '- None -']):
    '''Iterate over a column in a dataframe and blank out any fields containing a value in the sloplist IE: N/a, n/a, <none>, etc.'''
    column_data = []
    column_iloc = dataframe.columns.get_loc(column)
    for index, row in dataframe.iterrows():
        row_data = row[column_iloc]
        if row_data in placeholder_list:
            column_data.append('')
        else:
            column_data.append(row_data)
    dataframe = dataframe.drop(column, axis=1)
    dataframe[column] = column_data
    return(dataframe)

从单个库中丢弃所有占位符

df = drop_placeholders(df, colunm)

从整个数据框中删除所有占位符

for colunm in list(df):
    df = drop_placeholders(df, colunm)

我看到熊猫是内置的dropna()函数,但无法弄清楚如何指定占位符列表。

任何想法?

3 个答案:

答案 0 :(得分:2)

read_csvread_excel都接受一个na_values参数,在文档中对此进行了如下描述:

  

na_values :标量,str,类似列表或字典,默认为无

     

要识别为NA / NaN的其他字符串。如果dict通过,则具体   每列NA值。默认情况下,以下值被解释   如NaN:“,”,“#N / A”,“#N / A N / A”,“#NA”,“-1.#IND”,“-1.#QNAN”,“-NaN”,   '-nan','1.#IND','1.#QNAN','N / A','NA','NULL','NaN','n / a','nan',   “空”。

这意味着您可以在读取文件时传递额外的值,并且它应该更快。

基本上,您在哪里读取文件都可以

placeholders = ['N/A', 'N/a', 'n/a', 'NaN', 'none', '<none>', 'Unassigned', 'Not Reported', '- None -']
df = read_csv(filename, na_values=placeholders)

现在将读取占位符位置带有NaN的文件。要删除包含这些值的行,请使用dropna()

df = df.dropna(subset=[column])  # For a single column
df = df.dropna()  # for all rows containing nans
df = df.dropna(how='all')  # to drop only rows where all columns are nan

答案 1 :(得分:0)

迭代数据帧行将效率很低。重复这样做一定很痛苦。

您可以通过pd.Series.isinpd.DataFrame.loc使用布尔索引:

def drop_placeholders(df, col, L=['N/A', 'N/a', 'n/a', 'NaN', 'none', '<none>',
                                  'Unassigned', 'Not Reported', '- None -']):
    df.loc[df[col].isin(L), column] = ''
    return df

答案 2 :(得分:0)

或者,如果CSV文件不大,您也可以将CSV读入DataFrame并使用@jpp提到的屏蔽,并通过以下方式删除包含该文件的所有行:链接pd.DataFrame.isinpd.DataFrame.dropna。可能不是最有效的方法,但它是处理DataFrame对象而不遍历每一列的一种方法。

In [52]: df
Out[52]: 
     A    B         C
0    0   10       100
1    1  n/a       101
2    2   12       102
3  N/A   13       103
4    4   14  - None -
5    5   15       105
6    6   16       106
7    7   17       107
8    8   18       108
9    9   19       109


In [53]: df[-df.isin(placeholder_list)].dropna()
Out[53]: 
   A   B    C
0  0  10  100
2  2  12  102
5  5  15  105
6  6  16  106
7  7  17  107
8  8  18  108
9  9  19  109

请注意,在第二个代码中登录-