【问题标题】:Pandas: aggregate min, mean, and max of values from python list of nested dictionariesPandas:从嵌套字典的python列表中聚合最小值、平均值和最大值
【发布时间】:2022-02-13 07:58:12
【问题描述】:

我在 python 中有一个嵌套字典列表,其中包含我想使用 pandas 分析的数据。以下是一些示例数据:

[
  {
    "A": { "left": 1, "right": 2 },
    "B": { "left": 3, "right": 4 },
    "C": { "left": 5, "right": 6 },
  },
  {
    "A": { "left": 7, "right": 8 },
    "B": { "left": 9, "right": 10 },
    "C": { "left": 11, "right": 12 },
  },
  ...
]

等等。如示例所示,数组中的每一项都是具有相同键的字典,并且每个键都指向具有相同键的字典。在表格形式中,我想它应该是这样的:

|idx|A         |B         |C         |
|   |left|right|left|right|left|right|
--------------------------------------
| 0 |   1|    2|   3|    4|   5|    6|
| 1 |   7|    8|   9|   10|  11|   12|
| 2 | ...                            |

我想要做的是在这个字典列表中为每个字母聚合“左”和“右”的最小值、平均值和最大值,以便它最终得到一个这样的 DataFrame:

|idx|left_min|left_mean|left_max|right_min|right_mean|right_max|
----------------------------------------------------------------
| A |       1|        4|       7|        2|         5|        8|
| B |       3|        6|       9|        4|         7|       14|
| C |       5|        8|      11|        6|         9|       12|

我有使用 python 的经验,但对 pandas 比较陌生,所以我尝试在 pandas 框架中正确处理它,然后我自己用 python 编写它。我尝试了许多不同的方法来将 pandas DataFrames 塑造成这种形式,但我无法完全管理它。我所做的每一次尝试都以奇怪的方式进行了多重索引,或者无法正确聚合。我觉得我在这里缺少一些基本的东西。任何帮助表示赞赏。

【问题讨论】:

  • 这是列轴中的多索引。结帐thisthis
  • @MYousefi 如果我可以将字典列表转换为具有多索引列的 DataFrame,您知道如何像我正在寻找的那样聚合最小值、平均值和最大值吗?因为我可以迈出第一步,但我什至不确定这是否是最好的第一步。如果是,我可以包含我的代码以尝试这样做。
  • 你很勇敢地在原版 python 中尝试这个 :) 我会把它扔到数据库中,然后扔一些 SQL。
  • @Umar.H 哈,如果我知道任何 SQL,那么也许我会!我只是一个做一些基本分析的游戏开发者,我碰巧知道python。 :)

标签: python pandas


【解决方案1】:

让我们逐步解决这个问题。

pd.json_normalize

df = pd.json_normalize(data)

   A.left  A.right  B.left  B.right  C.left  C.right
0       1        2       3        4       5        6
1       7        8       9       10      11       12

str.split 用于多索引。

df.columns = df.columns.str.split('.',expand=True)

     A          B          C
  left right left right left right
0    1     2    3     4    5     6
1    7     8    9    10   11    12

stack.groupby.agg(['min','max','mean']) 用于那些讨厌的聚合。

df1 = df.stack(0).groupby(level=1).agg(['min','max','mean'])   


  left          right
   min max mean   min max mean
A    1   7  4.0     2   8  5.0
B    3   9  6.0     4  10  7.0
C    5  11  8.0     6  12  9.0

最后是一个简单的列表组合来展平你的列。

df1.columns = [f"{x}_{y}" for x,y in df1.columns]

print(df1)
   left_min  left_max  left_mean  right_min  right_max  right_mean
A         1         7        4.0          2          8         5.0
B         3         9        6.0          4         10         7.0
C         5        11        8.0          6         12         9.0
                        

或者更简洁的@sammywemmy

df1.columns = df1.columns.map('_'.join)

【讨论】:

  • df.columns = df.columns.map('_'.join)?
  • @sammywemmy 谢谢 :)
  • 太棒了!感谢您在这里提供非常干净的解决方案。我认为我缺少的关键部分是 a) 使用字符串操作的简单多索引,以及 b) stack(),我没有听说过并且肯定会进一步调查。此外,总的来说,我仍然只是围绕多索引进行思考,这很有帮助。谢谢!
猜你喜欢
  • 1970-01-01
  • 2017-12-15
  • 1970-01-01
  • 2017-08-05
  • 1970-01-01
  • 1970-01-01
  • 2015-01-16
  • 2014-07-09
  • 2015-08-05
相关资源
最近更新 更多