Rod*_*igo 2 dataframe python-3.x pandas
我对熊猫比较陌生,我不知道解决我的问题的最佳方法。好吧,我有一个 df :一个索引,以及一个名为“Data”的列和一个名为“sum”的空列中的数据。
我需要帮助来创建一个函数,以在列“总和”中添加“数据”列的可变行组的总和。分组标准是组中不应有空行。
这里有一个例子:
index Data Sum
0 1
1 1 2
2
3
4 1
5 1
6 1 3
7
8 1
9 1 2
10
11 1
12 1
13 1
14 1
15 1 5
16
17 1 1
18
19 1 1
20
Run Code Online (Sandbox Code Playgroud)
如您所见,'Data' 中每组数据的长度是可变的,可以是一行,也可以是任意数量的行。总和必须在组的末尾。例如:“数据”列的第 4、5、6 行组的总和应位于“总和”列的第 6 行。
任何见解将不胜感激。
更新
通过实施ansev建议的方法3解决了该问题。但是由于主程序的变化,每个块的总和,现在需要在每个块的开始处(如果块有多于一行)。然后我使用该df = df.iloc[::-1]指令两次以反转列并再次恢复正常。非常感谢!!!!!
df = df.iloc[::-1]
blocks = df['Data'].isnull().cumsum()
m = blocks.duplicated(keep='last')
df['Sum'] = df.groupby(blocks)['Data'].cumsum().mask(m)
df = df.iloc[::-1]
print(df)
Data Sum
0 1.0 2.0
1 1.0 NaN
2 NaN NaN
3 NaN NaN
4 1.0 3.0
5 1.0 NaN
6 1.0 NaN
7 NaN NaN
8 1.0 2.0
9 1.0 NaN
10 NaN NaN
11 1.0 5.0
12 1.0 NaN
13 1.0 NaN
14 1.0 NaN
15 1.0 NaN
16 NaN NaN
17 1.0 1.0
18 NaN NaN
19 1.0 1.0
20 NaN NaN
Run Code Online (Sandbox Code Playgroud)
我们可以使用GroupBy.cumsum:
# if you need replace blanks
#df = df.replace(r'^\s*$', np.nan, regex=True)
s = df['Data'].isnull()
df['sum'] = df.groupby(s.cumsum())['Data'].cumsum().where((~s) & (s.shift(-1)))
print(df)
index Data sum
0 0 1.0 NaN
1 1 1.0 2.0
2 2 NaN NaN
3 3 NaN NaN
4 4 1.0 NaN
5 5 1.0 NaN
6 6 1.0 3.0
7 7 NaN NaN
8 8 1.0 NaN
9 9 1.0 2.0
10 10 NaN NaN
11 11 1.0 NaN
12 12 1.0 NaN
13 13 1.0 NaN
14 14 1.0 NaN
15 15 1.0 5.0
16 16 NaN NaN
17 17 1.0 1.0
18 18 NaN NaN
19 19 1.0 1.0
20 20 NaN NaN
Run Code Online (Sandbox Code Playgroud)
方法二
#df = df.drop(columns='index') #if neccesary
g = df.reset_index().groupby(df['Data'].isnull().cumsum())
df['sum'] = g['Data'].cumsum().where(lambda x: x.index == g['index'].transform('idxmax'))
Run Code Online (Sandbox Code Playgroud)
方法三
Series.duplicated 和 Series.mask
blocks = df['Data'].isnull().cumsum()
m = blocks.duplicated(keep='last')
df['sum'] = df.groupby(blocks)['Data'].cumsum().mask(m)
Run Code Online (Sandbox Code Playgroud)
如您所见,这些方法仅在屏蔽值的方式上有所不同?我们不需要sum列中的值。
我们也可以使用.transform('sum'),而不是.cumsum()
示例数据帧的性能
%%timeit
s = df['Data'].isnull()
df['sum'] = df.groupby(s.cumsum())['Data'].cumsum().where((~s) & (s.shift(-1)))
4.52 ms ± 901 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%%timeit
g = df.reset_index().groupby(df['Data'].isnull().cumsum())
df['sum'] = g['Data'].cumsum().where(lambda x: x.index == g['index'].transform('idxmax'))
8.52 ms ± 1.45 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)
%%timeit
blocks = df['Data'].isnull().cumsum()
m = blocks.duplicated(keep='last')
df['sum'] = df.groupby(blocks)['Data'].cumsum().mask(m)
3.02 ms ± 172 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
121 次 |
| 最近记录: |