首页 > 解决方案 > Pandas:在组之前和之后动态添加行

问题描述

我有一个熊猫数据框:

pd.DataFrame(data={"Value": [5, 0, 0, 8, 0, 3, 0, 2, 7, 0], "Group": [1, 1, 1, 1, 2, 2, 2, 2, 2, 2]})

   Value  Group
0    5.0      1
1    0.0      1
2    0.0      1
3    8.0      1
4    0.0      2
5    3.0      2
6    0.0      2
7    2.0      2
8    7.0      2
9    0.0      2

我还计算了每组两行的累积总和:

{"2-cumsum Group 1": array([5., 8.]), "2-cumsum Group 2": array([7., 5.])}

例如array([5., 8.])因为array([5.0, 0.0])(rows 0 and 1) + array([0.0 + 8.0])(rows 2 and 3) = array([5., 8.])

我现在需要的是在 的开头df、每个组之间和末尾添加两行,df以便我得到以下数据框(间隙用于说明目的):

    Value  Group
0    10.0      0    # Initialize with 10.0
1    10.0      0    # Initialize with 10.0

2     5.0      1 
3     0.0      1
4     0.0      1
5     8.0      1

6     5.0      0    # 5.0 ("2-cumsum Group 1"[0])
7     2.0      0    # 8.0 ("2-cumsum Group 1"[1])

8     0.0      2
9     3.0      2
10    0.0      2
11    2.0      2
12    7.0      2
13    0.0      2

14    7.0      0    # 5.0 ("2-cumsum Group 2"[0])
15    5.0      0    # 8.0 ("2-cumsum Group 2"[1])

请考虑原始数据框要大得多,不仅仅是两列,我需要动态附加具有不同条目的行。例如,要追加的行应该有一个带有“10.0”条目的附加列。此外,计算关于某个整数(在本例中为 2)的累积和是可变的(可能是 8)。

在很多情况下,我需要根据数据帧中的其他行生成行,但除了使用 for 循环和一些保存先前迭代的值的临时缓存列表之​​外,我没有找到任何有效的解决方案。我会很感激一些帮助。预先感谢您和亲切的问候。


我的原始代码应用于示例数据,以防有人需要。它非常令人困惑且无效,因此仅在您确实需要时才考虑它:

import pandas as pd
import numpy as np

# Some stuff
df = pd.DataFrame(data={"Group1": ["a", "a", "b", "b", "b"],
                        "Group2": [1, 2, 1, 2, 3],
                       "Group3": [1, 9, 2, 1, 1],
                       "Value": [5, 8, 3, 2, 7]})

length = 2
max_value = 20

g = df['Group1'].unique()
h = df["Group2"].unique()
i = range(1,df['Group3'].max()+1)

df2 = df.set_index(['Group1','Group2','Group3']).reindex(pd.MultiIndex.from_product([g,h,i])).assign(cc = lambda x: (x.groupby(level=0).cumcount())//length).rename_axis(['Group1','Group2','Group3'],axis=0)
df2 = df2.loc[~df2['Value'].isna().groupby([pd.Grouper(level=0),df2['cc']]).transform('all')].reset_index().fillna(0).drop('cc',axis=1)

values = df2["Value"].copy().to_numpy()
values = np.array_split(values, len(values)/length) 
stock = df2["Group1"].copy().to_numpy() 
stock = np.array_split(stock, len(stock)/length)

# Generate the "Group" column and generate the "2-cumsum" arrays 
# stored in the "volumes" variable
k = 0
a_groups = []
values_cache = []
volumes = []
for e, i in enumerate(values):
        if any(stock[e] == stock[e-1]):
            if np.any(i + values_cache >= max_value):
                k += 1
                volumes.append(values_cache)
                values_cache = i
            else:
                values_cache += i
            a_groups.extend([k] * length)
        else:
            k += 1
            if e:
                volumes.append(values_cache)
            values_cache = i
            a_groups.extend([k] * length)
volumes.append(values_cache)
df2["Group"] = a_groups

print(df2[["Value", "Group"]])
print("\n")
print(f"2-cumsums: {volumes}")

"""Output

   Value  Group
0    5.0      1
1    0.0      1
2    0.0      1
3    8.0      1
4    0.0      2
5    3.0      2
6    0.0      2
7    2.0      2
8    7.0      2
9    0.0      2

2-cumsums: [array([5., 8.]), array([7., 5.])]"""

标签: pythonpandasnumpypandas-groupbycumsum

解决方案


推荐阅读