Python 熊猫:根据列中的条件测试替换记录

Python 熊猫:根据列中的条件测试替换记录,python,pandas,replace,conditional,records,Python,Pandas,Replace,Conditional,Records,我在一个数据框中有唯一的记录,没有重复记录,这是由跨多个列的值组合决定的: import pandas as pd d = {'Alpha' : ['C', 'B', 'C','D', 'A', 'A'], 'Beta' : ['G', 'F', 'G', 'H', 'A', 'A'],'Year': ['Base', 88, 94, 22, 'Base', 66], 'Zulu' : [1, 2, -3, 4, 5, -3]} df = pd.DataFrame(d) 这让我们:

我在一个数据框中有唯一的记录,没有重复记录,这是由跨多个列的值组合决定的:

import pandas as pd
d = {'Alpha' : ['C', 'B', 'C','D', 'A', 'A'], 'Beta' : ['G', 'F', 'G', 'H', 'A', 'A'],'Year': ['Base', 88, 94, 22, 'Base', 66], 'Zulu' : [1, 2, -3, 4, 5, -3]}
df = pd.DataFrame(d)   
这让我们:

  Alpha Beta  Year  Zulu
0     C    G  Base     1
1     B    F    88     2
2     C    G    94    -3
3     D    H    22     4
4     A    A  Base     5
5     A    A    66    -4
指数0与指数2接近匹配,指数4与指数5接近匹配,但指数0和指数4的“年”值为基数,指数2和5的“祖鲁”值为负值。我想用索引0和4中相应的Zulu值替换2和5中的负“Zulu”值,而不中断其他行。输出df如下所示:

  Alpha Beta  Year  Zulu
0     C    G  Base     1
1     B    F    88     2
2     C    G    94     1
3     D    H    22     4
4     A    A  Base     5
5     A    A    66     5
我可以轻松地从筛选和深度拷贝开始,以避免切片问题,然后备份原始数据:

df_sub = df[df.Zulu < 0].copy(deep=True)
df_sub['Zulu_backup'] = df_sub.Zulu
导致:

Alpha Beta  Year    Zulu     Zulu_backup
0     C    G    94    -3         -3.0
1     A    A    66    -3         -3.0
2     C    G  Base     1          NaN
3     B    F    88     2          NaN
4     D    H    22     4          NaN
5     A    A  Base     5          NaN

但我不知道从这里可以走到哪里,而不会弄乱数据帧的其他行。我有一个相当复杂的剧本。我猜我可以创建一个系列并将其映射到数据帧,但我不知道如何做到这一点。迭代这不是一个选项,因为我有数百万行。非常感谢您的帮助。

一种方法是将Zulu中的负值转换为nan,然后再填充nan

df.loc[df['Zulu'] < 0, 'Zulu'] = np.nan
df['Zulu'] = df.groupby(['Alpha', 'Beta']).Zulu.apply(lambda x: x.ffill().bfill()).astype(int)


    Alpha   Beta    Year    Zulu
0   C       G       Base    1
1   B       F       88      2
2   C       G       94      1
3   D       H       22      4
4   A       A       Base    5
5   A       A       66      5
df.loc[df['Zulu']<0'Zulu']=np.nan
df['Zulu']=df.groupby(['Alpha','Beta']).Zulu.apply(lambda x:x.ffill().bfill()).astype(int)
阿尔法-贝塔年祖鲁
0 C G基1
1 B F 88 2
2 C G 94 1
三维H 22 4
4 A基地5
5 A 66 5

一种方法是将Zulu中的负值转换为nan,然后再填充nan

df.loc[df['Zulu'] < 0, 'Zulu'] = np.nan
df['Zulu'] = df.groupby(['Alpha', 'Beta']).Zulu.apply(lambda x: x.ffill().bfill()).astype(int)


    Alpha   Beta    Year    Zulu
0   C       G       Base    1
1   B       F       88      2
2   C       G       94      1
3   D       H       22      4
4   A       A       Base    5
5   A       A       66      5
df.loc[df['Zulu']<0'Zulu']=np.nan
df['Zulu']=df.groupby(['Alpha','Beta']).Zulu.apply(lambda x:x.ffill().bfill()).astype(int)
阿尔法-贝塔年祖鲁
0 C G基1
1 B F 88 2
2 C G 94 1
三维H 22 4
4 A基地5
5 A 66 5
编辑:

df.Zulu=df.Zulu.mask(df.Zulu.lt(0))

df.Zulu=df.set_index(['Alpha','Beta']).Zulu.fillna(df.set_index(['Alpha','Beta']).dropna().Zulu).values
df
Out[89]: 
  Alpha Beta  Year  Zulu
0     C    G  Base   1.0
1     B    F    88   2.0
2     C    G    94   1.0
3     D    H    22   4.0
4     A    A  Base   5.0
5     A    A    66   5.0
编辑:


我认为我们不需要在这里应用df.groupby(['Alpha','Beta']).Zulu.ffill().astype(int)仍然是一个很好的方法:-)@Wen,您提出的解决方案只有在正值先于负值的情况下才有效。将最后的5和-4翻转到-5和-4,它将不起作用现在你的解决方案看起来更紧凑了,你得到了我的支持:)我想我们不需要在这里应用
df.groupby(['Alpha',Beta']).Zulu.ffill().astype(int)
仍然是一个很好的解决方案:-@Wen,你提出的解决方案只有在正值先于负值的情况下才会起作用。将最后的5和-4翻转到-5和-4,它将不起作用现在您的解决方案看起来更加紧凑,您得到了我的支持:)