python - Pandas 数据帧 : How to groupby and sort "by blocks"?

标签 python pandas dataframe sorting pandas-groupby

我正在使用包含如下数据的 DataFrame,并以两种不同的方式对数据进行分组。

>>> d = {
     "A": [100]*7 + [200]*7,
     "B": ["one"]*4 + ["two"]*3 + ["one"]*3 + ["two"]*4,
     "C": ["foo"]*3 + ["bar"] + ["foo"] + ["bar"]*2 + ["foo"]*2 + ["bar"] + ["foo"]*3 + ["bar"],
     "D": ["yay"] + ["nay"]*2 + ["yay"] + ["nay"]*3 + ["yay"] + ["nay"] + ["yay"]*3 + ["nay"] + ["yay"],
     "X": [2, 8, 3, 5, 1, 4, 3, 2, 6, 5, 1, 2, 4, 7]
    }

>>> df = pd.DataFrame(d)
>>> df

     A    B    C    D    X
0  100  one  foo  yay    2
1  100  one  foo  nay    8
2  100  one  foo  nay    3
3  100  one  bar  yay    5
4  100  two  foo  nay    1
5  100  two  bar  nay    4
6  100  two  bar  nay    3
7  200  one  foo  yay    2
8  200  one  foo  nay    6
9  200  one  bar  yay    5
10 200  two  foo  yay    1
11 200  two  foo  yay    2
12 200  two  foo  nay    4
13 200  two  bar  yay    7

>>> df_grp = df.groupby(['A', 'B'])
>>> df_grp_sorted = df_grp.sum().sort_values('X', ascending = False)
>>> df_grp_long = df.groupby(['A', 'B', 'C', 'D'])
>>> df_grp_sorted_long = df_grp_long.sum().sort_values('X', ascending = False)

这给了我们:

>>> df_grp_sorted

            X
100  one   18
200  two   14
     one   13
100  two    8


>>> df_grp_sorted_long

                      X
100  one  foo  nay   11
     two  bar  nay    7
200  two  bar  yay    7
     one  foo  nay    6
100  one  bar  yay    5
200  one  bar  yay    5
     two  foo  nay    4
               yay    3
100  one  foo  yay    2
200  one  foo  yay    2    
100  two  foo  nay    1

现在,我想要 df_grp_sorted_long 的详细信息,以及 df_grp_sorted 的结构。那将是:

>>> df_result

                      X
100  one  foo  nay   11
               yay    5
          foo  yay    2
200  two  bar  yay    7
          foo  nay    4
               yay    3
     one  foo  nay    6
          bar  yay    5
          foo  yay    2    
100  two  bar  nay    7
          foo  nay    1
          

我用下面的代码完成了这个(这违背了 this post 的建议):

>>> col_names = ['A', 'B', 'C', 'D']
>>> df_result = pd.DataFrame(columns=col_names)
>>> for (i, (a, b)) in enumerate(df_grp_sorted.index):
        df_result = pd.concat(
            (
                df_result,
                (df[(df['A']==a) & (df['B']==b)]
                .groupby(col_names)
                .sum()
                .sort_values('X', ascending=False)
                )
            )
        )
>>> df_result = df_result["X"]

这给出了正确的答案,但对于大数据集来说速度很慢。我还想知道是否有一种 native 方法可以进行这种分组/排序组合。

此外,也许这种方法不是正确的方法,并且有一种更简单的方法来获得等效方法的结果?

最佳答案

另一种方法是合并两个帧。使用您在上面提供的内容:

import pandas as pd

d = {"A": [100] * 7 + [200] * 7,
     "B": ["one"] * 4 + ["two"] * 3 + ["one"] * 3 + ["two"] * 4,
     "C": ["foo"] * 3 + ["bar"] + ["foo"] + ["bar"] * 2 + ["foo"] * 2 + ["bar"] + ["foo"] * 3 + ["bar"],
     "D": ["yay"] + ["nay"] * 2 + ["yay"] + ["nay"] * 3 + ["yay"] + ["nay"] + ["yay"] * 3 + ["nay"] + ["yay"],
     "X": [2, 8, 3, 5, 1, 4, 3, 2, 6, 5, 1, 2, 4, 7]}

df = pd.DataFrame(data=d)
df_grp_sorted = df.groupby(["A", "B"], as_index=False).sum().sort_values("X", ascending=False)
df_grp_long = df.groupby(["A", "B", "C", "D"], as_index=False)
df_grp_sorted_long = df_grp_long.sum().sort_values("X", ascending=False)
df_result = (df_grp_sorted
             .merge(df_grp_sorted_long, how="outer", on=["A", 'B'])
             .drop(columns=["X_x"])
             .rename(columns={"X_y": "X"}))

输出

<表类="s-表"> <头> A B C D <日>X <正文> 100 一个 富 没有 11 100 一个 栏 是的 5 100 一个 富 是的 2 200 两个 栏 是的 7 200 两个 富 没有 4 200 两个 富 是的 3 200 一个 富 没有 6 200 一个 栏 是的 5 200 一个 富 是的 2 100 两个 栏 没有 7 100 两个 富 没有 1

关于python - Pandas 数据帧 : How to groupby and sort "by blocks"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72146107/

相关文章:

python pandas TimeStamps到具有夏令时的本地时间字符串

python - 分配给 pandas DataFrame 中的新列时令人费解的 KeyError

r - 按值选择多个观察值

python - 在 Matplotlib 中使用获取和设置轴方法的相对坐标

python - 当我从 pandas DataFrame 中采样一行后,如何获取一个单元格的值?

python - 如何使用 pyinstaller 制作 vpython .exe

pandas - 迭代 Pyarrow 表的最快方法

python - 每月总计和累计总和 - Pandas

Python - pysftp/paramiko - 使用指纹验证主机 key

python - 展平 pandas df 的时间序列数据