熊猫:基于函数有效地更新列值

时间:2019-08-05 19:10:12

标签: python pandas dataframe

我将用一个小例子来总结我正在尝试做的事情。假设我们有一个数据框,其中包含以下所示的两列(大约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,所以遇到了很多麻烦!

我们将不胜感激!

1 个答案:

答案 0 :(得分:1)

如果要将0.0的值替换为组的中位数,则可以使用.mask0.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