我试图通过检查列X的前9行和当前行值来计算每行的新列Y.基本上每行的新列Y值将告诉我们列X的值的百分比更大包括当前记录在内的前10个记录中的1个以上。下面是我正在使用的代码,但获得的结果与预期不同
[EDITED]
def count_pcnt(x):
return ((np.sum(x > 1) / len(x)) * 100.0)
def run():
df = pd.DataFrame(
data={'X': ['8.12', '7.13', '-5.30', '3.21', '4.21', '3.14','8.65',
'7.33', '-5.10', '3.01']
})
df['Y'] = df['X'].rolling(window=10, min_periods=1).apply(lambda x:
count_pcnt(x)).apply(int)
预期结果 [已编辑]
X Y(%)
0 8.12 100
1 7.13 100
2 -5.30 66.67
3 3.21 75
4 4.21 80
5 3.14 83.33
6 8.65 85.71
7 7.33 87.50
8 -5.10 77.77
9 3.01 80
实际
X Y
0 8.12 100
1 7.13 100
2 -5.30 0
3 3.21 0
4 4.21 0
5 3.14 0
6 8.65 0
7 7.33 0
8 -5.10 0
9 3.01 0
更新我使用了下面推荐的这个选项并且它有效。虽然还有其他选择,我觉得这更清洁
df['Y'] = df['X'].astype(float)
.rolling(window=w, min_periods=1)
.apply(lambda x: (x>1).mean()) * 100
如果你想根据接下来的10行计算列值而不是前10行 - 下面是解决方案(感谢 jezrae l提供了它)
df['Y'] = (df['X'].astype(float).iloc[::-1].rolling(window=10, min_periods=1).apply(lambda x: (x>1).mean()) * 100)[::-1]
答案 0 :(得分:2)
您可以在df.rolling
中设置min_periods=1
属性:
In [927]: def count_pcnt(x):
...: return ((np.sum(x > 1) / len(x)) * 100.0)
...:
In [930]: df['Y'] = df['X'].astype(np.float64).rolling(window=10, min_periods=1).apply(lambda x: count_pcnt(x))
In [931]: df
Out[931]:
X Y
0 8.12 100.000000
1 7.13 100.000000
2 -5.30 66.666667
3 3.21 75.000000
4 4.21 80.000000
5 3.14 83.333333
6 8.65 85.714286
7 7.33 87.500000
8 -5.10 77.777778
9 3.01 80.000000
我修改了您的count_pcnt
功能,以考虑传递的可变窗口大小。我相信这就是你要找的东西。
答案 1 :(得分:1)
似乎X的数据类型是object而不是float。请尝试以下操作以查看它是否有效。
df['Y'] = (
df.assign(X2=(df.X.astype(float)>0)).X2.rolling(window=10,min_periods=1)
.apply(lambda x: sum(x)*100.0/len(x))
)
df
Out[92]:
X Y
0 8.12 100.000000
1 7.13 100.000000
2 -5.30 66.666667
3 3.21 75.000000
4 4.21 80.000000
5 3.14 83.333333
6 8.65 85.714286
7 7.33 87.500000
8 -5.10 77.777778
9 3.01 80.000000
答案 2 :(得分:1)
您可以使用:
astype
X
转换为float
min_periods
添加到Series.rolling
(x>1).mean()
具有相同的输出df = pd.DataFrame(
data={'X': ['8.12', '7.13', '-5.30', '3.21', '4.21', '3.14','8.65',
'7.33', '-5.10', '3.01']
})
w = 10
df['Y'] = df['X'].astype(float)
.rolling(window=w, min_periods=1)
.apply(lambda x: (x>1).mean()) * 100
print(df)
X Y
0 8.12 100.000000
1 7.13 100.000000
2 -5.30 66.666667
3 3.21 75.000000
4 4.21 80.000000
5 3.14 83.333333
6 8.65 85.714286
7 7.33 87.500000
8 -5.10 77.777778
9 3.01 80.000000
自定义功能解决方案:
def count_pcnt(x):
return ((np.sum(x>1))/ len(x))*100.0
w = 10
df['Y'] = df['X'].astype(float).rolling(window=w, min_periods=1).apply(count_pcnt)
print(df)
X Y
0 8.12 100.000000
1 7.13 100.000000
2 -5.30 66.666667
3 3.21 75.000000
4 4.21 80.000000
5 3.14 83.333333
6 8.65 85.714286
7 7.33 87.500000
8 -5.10 77.777778
9 3.01 80.000000
编辑:
可以通过以下方式更改功能:
def count_pcnt(x):
return ((x>1).sum() / len(x))*100.0
或:
def count_pcnt(x):
return (x>1).mean()*100.0