我可以请求更高效(更快)迭代的建议吗? 这是问题,我正在寻找一种方法在确定的窗口大小内在pandas DataFrame中传播零:
<input type="button" id="createPassSubmit" value="Create">
现在我们想要通过增加每行3行的窗口来填充 顶部的值。 每行3行的窗口从window_start开始,定义为:
import numpy as np
import pandas as pd
A = np.matrix([[ 0., 1., 1., 1., 1.],
[ 1., 0., 1., 1., 1.],
[ 1., 1., 0., 1., 1.],
[ 1., 1., 1., 0., 1.],
[ 1., 1., 1., 1., 0.],
[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 0.],
[ 1., 1., 0., 1., 1.],
[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 0., 1.],
[ 1., 1., 1., 1., 1.],
[ 1., 1., 0., 1., 1.],
[ 1., 1., 1., 1., 0.],
[ 1., 0., 1., 1., 1.],
[ 1., 1., 1., 1., 1.]])
df = pd.DataFrame(A)
现在将DataFrame从零传播到零 在该窗口内的上面一行:
window_size = 3
window_start = [i for i in range(0, df.shape[0])
if i % window_size == 0]
print(df)
gf = df.copy()
print('\n')
对于非常大的数据集来说,这最后一点非常低效且耗时,是否有更好的方法呢?
答案 0 :(得分:8)
您应该能够使用groupby
内的累积产品完成此任务。
df.groupby(np.arange(len(df)) // 3).cumprod()
0 1 2 3 4
0 0.0 1.0 1.0 1.0 1.0
1 0.0 0.0 1.0 1.0 1.0
2 0.0 0.0 0.0 1.0 1.0
3 1.0 1.0 1.0 0.0 1.0
4 1.0 1.0 1.0 0.0 0.0
5 1.0 1.0 1.0 0.0 0.0
6 1.0 1.0 1.0 1.0 1.0
7 1.0 1.0 1.0 1.0 1.0
8 1.0 1.0 1.0 1.0 0.0
9 1.0 1.0 0.0 1.0 1.0
10 1.0 1.0 0.0 1.0 1.0
11 1.0 1.0 0.0 1.0 1.0
12 1.0 1.0 1.0 1.0 1.0
13 1.0 1.0 1.0 1.0 1.0
14 1.0 1.0 1.0 0.0 1.0
15 1.0 1.0 1.0 1.0 1.0
16 1.0 1.0 0.0 1.0 1.0
17 1.0 1.0 0.0 1.0 0.0
18 1.0 0.0 1.0 1.0 1.0
19 1.0 0.0 1.0 1.0 1.0
我们可以更好地了解一下,使用concat
查看它是否正在执行我们想要的操作。
pd.concat([df.iloc[:6, :2], d1.iloc[:6, :2]], axis=1, keys=['Before', 'After'])
Before After
0 1 0 1
0 0.0 1.0 0.0 1.0
1 1.0 0.0 0.0 0.0
2 1.0 1.0 0.0 0.0
3 1.0 1.0 1.0 1.0
4 1.0 1.0 1.0 1.0
5 1.0 1.0 1.0 1.0
我采用numpy
方法
请参阅@Divakar的解决方案,因为我借用了其功能的一些元素
def prop_zero(df, window_size=3):
a = df.values
W = window_size
m, n = a.shape
pad = np.zeros((W - m % W, n))
b = np.vstack([a, pad])
return pd.DataFrame(
b.reshape(-1, W, n).cumprod(1).reshape(-1, n)[:m],
df.index, df.columns
)
prop_zero(df)
答案 1 :(得分:5)
您可以使用groupby
执行cummin
:
In [46]: out = df.groupby(np.arange(len(df))//3).cummin()
In [47]: df.head(6)
Out[47]:
0 1 2 3 4
0 0.0 1.0 1.0 1.0 1.0
1 1.0 0.0 1.0 1.0 1.0
2 1.0 1.0 0.0 1.0 1.0
3 1.0 1.0 1.0 0.0 1.0
4 1.0 1.0 1.0 1.0 0.0
5 1.0 1.0 1.0 1.0 1.0
In [48]: out.head(6)
Out[48]:
0 1 2 3 4
0 0.0 1.0 1.0 1.0 1.0
1 0.0 0.0 1.0 1.0 1.0
2 0.0 0.0 0.0 1.0 1.0
3 1.0 1.0 1.0 0.0 1.0
4 1.0 1.0 1.0 0.0 0.0
5 1.0 1.0 1.0 0.0 0.0
这假设所有值都是0和1.如果你有非1值,但你仍然想要零之后的行为,你可以做类似的事情
df.where(~(df == 0).groupby(np.arange(len(df))//3).cummax(), 0)
这不是很漂亮,但不会被像0.5这样的值(直接将cummin
直接应用于值)或潜在溢出(将cumprod
直接应用于值)所迷惑一样)。