使用Python / Pandas我试图通过创建两个新列(A
和B
)来转换数据帧,条件是来自不同行(来自列ID3
)的值,但是来自在同一组内(由ID1
确定)。
对于每个ID1
组,我想取ID2
ID3
等于31
的{{1}}值,并将此值放在名为A
的新列中条件ID3
为1
或2
。同样,我想在ID2
等于ID3
的{{1}}值,并将此值放在名为41
的新列中,同样以B
为条件是ID3
或1
。
假设我有一个以下格式的数据帧:
2
转换后的格式应如下所示。使用import pandas as pd
df = pd.DataFrame({'ID1': (1, 1, 1, 1, 2, 2, 2), 'ID2': (151, 152, 153, 154, 261, 262, 263), 'ID3': (1, 2, 31, 41, 1, 2, 41), 'ID4': (2, 2, 1, 2, 1, 1, 2)})
print(df)
ID1 ID2 ID3 ID4
0 1 151 1 2
1 1 152 2 2
2 1 153 31 1
3 1 154 41 2
4 2 261 1 1
5 2 262 2 1
6 2 263 41 2
中的值填充A
和B
列的位置,以ID2
中的值为条件。
ID3
我尝试使用下面显示的内容,但变换将保留与原始数据集相同数量的值。这对 ID1 ID2 ID3 ID4 A B
0 1 151 1 2 153 154
1 1 152 2 2 153 154
2 1 153 31 1
3 1 154 41 2
4 2 261 1 1
5 2 262 2 1 263
6 2 263 41 2 263
= ID3
或31
的行造成问题。此外,如果组内41
的值ID2
没有ID2
,则默认情况下会返回31
值。
df['A'] = df.groupby('ID1')['ID2'].transform(lambda x: x.loc[df['ID3'] == 31])
df['B'] = df.groupby('ID1')['ID2'].transform(lambda x: x.loc[df['ID3'] == 41])
结果:
ID1 ID2 ID3 ID4 A B
0 1 151 1 2 153 154
1 1 152 2 2 153 154
2 1 153 31 1 153 154
3 1 154 41 2 153 154
4 2 261 1 1 261 263
5 2 262 2 1 262 263
6 2 263 41 2 263 263
有什么建议吗?提前谢谢!
答案 0 :(得分:0)
我不知道为什么这是最好的解决方案,但它是一个解决方案。
您可以将.loc
替换为.where
,如果条件不成立,则NaN
将返回NaN
。然后回填.where
,然后再次使用ID3
上的df['A'] = df.groupby('ID1')['ID2'].transform(lambda x:
x.where(df.ID3==31).fillna(method='bfill').where(df.ID3.isin([1,2])))
df['B'] = df.groupby('ID1')['ID2'].transform(lambda x:
x.where(df.ID3==41).fillna(method='bfill').where(df.ID3.isin([1,2])))
ID1 ID2 ID3 ID4 A B
0 1 151 1 2 153.0 154.0
1 1 152 2 2 153.0 154.0
2 1 153 31 1 NaN NaN
3 1 154 41 2 NaN NaN
4 2 261 1 1 NaN 263.0
5 2 262 2 1 NaN 263.0
6 2 263 41 2 NaN NaN
进行过滤,即1或2
void onLocationChanged(Location location){
long currentTime=location.getTime(); // unix time in milliseconds
.......
sendUpdates(currentTime);
}