我将用一个小例子来总结我正在尝试做的事情。假设我们有一个数据框,其中包含以下所示的两列(大约15列):
change period
0 -1 1
1 -1 1
2 0.0 1
3 -1 1
4 1 2
5 1 2
6 0.0 2
7 0.0 2
8 1 2
9 -1 3
...
...
这将扩展到大约2500万个数据条目。 本质上,我想更改数据帧中change列下的每个0.0,以获取其时间段内的方向值(因此,-1或+1,代表方向),不包括该时间段中的第一个条目。>
目前我正在运行以下程序,但是有这么多数据条目,我无法花几个小时:
def getPeriodDirection(period):
val = df.loc[(df['period'] == period) & (df['change'] != 0.0) , 'change'].median()
return val
df['change'] = df.apply(lambda row : getPeriodDirection(row['period']) if row['change'] == 0.0 else row['change'] , axis=1)
我尝试了几种使用.locs的方法,但是我无法完全按照自己的需要获得它。我尝试了以下方法:
directionNoChange = df['change'].isin(range(0,1))
df.loc[directionNoChange, 'change'] = getPeriodDirection(df, df['period'])
此解决方案使我非常接近。当'change'= 0.0时,我最终有了一个带有原始索引的数据框,并使用函数中的正确值对其进行了更新。根据示例,它将生成:
change
2 -1
6 1
7 1
下一步将是在定位索引的原始数据帧上的loc数据帧中替换此值。但是由于我不熟悉API,所以遇到了很多麻烦!
我们将不胜感激!
答案 0 :(得分:1)
如果要将0.0
的值替换为组的中位数,则可以使用.mask
将0.0
的值转换为NaN
,然后填写它们与median
。
print(df)
change period
0 -1.0 1
1 -1.0 1
2 0.0 1
3 -1.0 1
4 1.0 2
5 1.0 2
6 0.0 2
7 0.0 2
8 1.0 2
9 -1.0 3
# mask takes a condition and fills the True values with NaN
print(df.change.mask(cond = df.change == 0))
0 -1.0
1 -1.0
2 NaN
3 -1.0
4 1.0
5 1.0
6 NaN
7 NaN
8 1.0
9 -1.0
Name: change, dtype: float64
# use the other parameter similar to a fillna method
df['change'] = df.change.mask(cond = df.change == 0, other = df.groupby('period').change.transform('median'))
print(df)
change period
0 -1.0 1
1 -1.0 1
2 -1.0 1
3 -1.0 1
4 1.0 2
5 1.0 2
6 1.0 2
7 1.0 2
8 1.0 2
9 -1.0 3