根据其他行中其他列的匹配值更新列的NULL填充行

时间:2017-07-27 09:41:05

标签: python python-3.x pandas

假设我有一个如下数据框:

df1= name street city coordinates 0 A0 B0 C0 1,1 1 A1 B0 C0 NaN 2 A2 B0 C0 NaN 3 A3 B2 C2 NaN 4 A4 B2 C2 2,3 5 A5 B3 C3 NaN 6 A6 B3 C3 NaN

我希望结果是

df1= name street city coordinates 0 A0 B0 C0 1,1 1 A1 B0 C0 1,1 2 A2 B0 C0 1,1 3 A3 B2 C2 2,3 4 A4 B2 C2 2,3 5 A5 B3 C3 NaN 6 A6 B3 C3 NaN 我想使用相同的 街道 city <更新 坐标 / strong>即可。 在上面的示例(B0,C0)中,索引0处具有坐标(1,1)。所以我需要将索引1和2处的坐标更新为(1,1),因为它们具有相同的街道和城市(B0,C0)。 实现这一目标的最佳方法是什么?

如果给出数据帧列表,如何以类似的方式更新所有数据帧。即 df_list = [df1,df2,..] 首先使用所有数据帧中的唯一行生成数据帧,然后使用此数据框进行查找并更新每个数据帧,这是一个好主意吗?

1 个答案:

答案 0 :(得分:3)

如果每个组中只有一个非NaN值可以使用sort_valuesffillSeries.fillnamethod='ffill'):

df = df.sort_values(['street','city','coordinates'])
df['coordinates'] = df['coordinates'].ffill()
print (df)
  name street city coordinates
0   A0     B0   C0         1,1
1   A1     B0   C0         1,1
2   A2     B0   C0         1,1
4   A4     B2   C2         2,3
3   A3     B2   C2         2,3
5   A5     B2   C2         2,3
5   A6     B2   C2         2,3

GroupBy.transformdropna的解决方案:

df['coordinates'] = df.groupby(['street','city'])['coordinates']
                      .transform(lambda x: x.dropna())
print (df)
  name street city coordinates
0   A0     B0   C0         1,1
1   A1     B0   C0         1,1
2   A2     B0   C0         1,1
3   A3     B2   C2         2,3
4   A4     B2   C2         2,3
5   A5     B2   C2         2,3
5   A6     B2   C2         2,3

ffillbfill

df['coordinates'] = df.groupby(['street','city'])['coordinates']
                      .transform(lambda x: x.ffill().bfill())
print (df)
  name street city coordinates
0   A0     B0   C0         1,1
1   A1     B0   C0         1,1
2   A2     B0   C0         1,1
3   A3     B2   C2         2,3
4   A4     B2   C2         2,3
5   A5     B2   C2         2,3
5   A6     B2   C2         2,3

第二个解决方案也适用于多个值 - 每个组的第一个前向填充值(不替换第一个值,保留NaN),然后通过反向填充替换所有第一个值:

print (df)
  name street city coordinates
0   A0     B0   C0         1,1
1   A1     B0   C0         NaN
2   A2     B0   C0         NaN
3   A3     B2   C2         NaN
4   A4     B2   C2         2,3
5   A5     B2   C2         4,7
5   A6     B2   C2         NaN

df['coordinates'] = df.groupby(['street','city'])['coordinates']
                      .transform(lambda x: x.ffill().bfill())
print (df)
  name street city coordinates
0   A0     B0   C0         1,1
1   A1     B0   C0         1,1
2   A2     B0   C0         1,1
3   A3     B2   C2         2,3
4   A4     B2   C2         2,3
5   A5     B2   C2         4,7
5   A6     B2   C2         4,7