pandas DataFrame的条件替换

时间:2016-11-20 23:20:31

标签: python pandas

我有以下pandas DataFrame

ID  COL1  COL2
123 1     ABC
123 1     CCC
123 NaN   AVV
345 2     FGG
345 NaN   FRG
345 NaN   FGT 

我需要根据相同的Col1替换ID中的所有NaN值才能获得此结果:

ID  COL1  COL2
123 1     ABC
123 1     CCC
123 1     AVV
345 2     FGG
345 2     FRG
345 2     FGT 

我可以编写for循环,但我的数据集执行脚本需要很长时间。是否有任何条件替换功能?

2 个答案:

答案 0 :(得分:1)

如何使用Series.isnull()选择行和Series.map()来进行条件替换呢?

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'ID': [123, 123, 123, 345, 345, 345],
    'COL1': [1, 1, np.nan, 2, np.nan, np.nan],
    'COL2':['ABC', 'CCC', 'AVV', 'FGG', 'FRG', 'FGT']},
    columns=['ID','COL1', 'COL2'])

print df
mapping = {123: 1, 345: 2}
df.loc[df['COL1'].isnull(), 'COL1'] = df['ID'].map(mapping)
print df

之前:

    ID  COL1 COL2
0  123   1.0  ABC
1  123   1.0  CCC
2  123   NaN  AVV
3  345   2.0  FGG
4  345   NaN  FRG
5  345   NaN  FGT

后:

    ID  COL1 COL2
0  123   1.0  ABC
1  123   1.0  CCC
2  123   1.0  AVV
3  345   2.0  FGG
4  345   2.0  FRG
5  345   2.0  FGT

编辑:要以编程方式构建mapping,您可以使用以下两行代码:

df_unique = df.loc[df['COL1'].notnull()].groupby('ID').nth(0)
mapping = pd.Series(df_unique['COL1'].values, index=df_unique.index).to_dict()

答案 1 :(得分:1)

从以下示例开始:

df = pd.DataFrame({'ID': list(range(10)), 'COL1': [np.random.choice([1,np.nan]) for _ in range(10)]})
df = pd.concat([df]*100000).reset_index(drop = True)

df.head()

#  COL1 ID
#0  NaN  0
#1  1.0  1
#2  1.0  2
#3  NaN  3
#4  1.0  4

您可以使用每个组中的向前填充和向后填充方法来填充缺失值:

%timeit df.groupby('ID').ffill().bfill()
1 loop, best of 3: 212 ms per loop

或者另一种方法是按IDCOL1对值进行排序,首先对ID进行排序,然后在每个COL1内排序ID,这会导致所有丢失值到每个ID的末尾,然后您可以使用ffill(),这似乎比上面的ffill()bfill()方法更快:

%timeit df.sort_values(['ID', 'COL1']).ffill()
10 loops, best of 3: 71.6 ms per loop

如果还有其他不需要的字符串,您可以调用replace方法首先用NaN替换字符串。例如,如果要填充的数据框中有空字符串。你可以df.replace('', np.nan).sort_values(['ID', 'COL1']).ffill()