Python Pandas:Groupby并聚合多个json、float类型的列

Python Pandas:Groupby并聚合多个json、float类型的列,python,python-3.x,pandas,Python,Python 3.x,Pandas,我正在使用python3和pandas版本0.25。我在postgresql表中有一个JSON数据类型。我正在使用pandas.io.sql从表中获取数据 import pandas.io.sql as psql df = psql.read_sql(sql,con,params=params) 所以我从上面的DB调用中获取数据帧 当我检查df的输出(使用IDE)时,我会看到以下数据帧: 我想汇总数据;为了简单起见,仅选择了3列。我需要按col1_数据分组。我想要如下: 基本上,它是在多个

我正在使用python3和pandas版本0.25。我在postgresql表中有一个JSON数据类型。我正在使用pandas.io.sql从表中获取数据

import pandas.io.sql as psql
df = psql.read_sql(sql,con,params=params)
所以我从上面的DB调用中获取数据帧

当我检查df的输出(使用IDE)时,我会看到以下数据帧:

我想汇总数据;为了简单起见,仅选择了3列。我需要按col1_数据分组。我想要如下:

基本上,它是在多个列上聚合的。但主要问题是合并json列。在这里,哪个聚合函数可以帮助我

基于前面的帮助,为了使用lambda合并json列,我尝试如下所示。然而,它不起作用。我试着先使用json列,其他的可以简单求和

df = df.groupby(['col1_data']).apply(lambda row: [{**x} for x in row['col2_data']])
我得到一个错误:

'list' object is not a mapping
有人能帮我吗?谢谢

更新:

f = (df
    .groupby('col1_data')['col2_data']
    .apply(lambda x: np.concatenate(x.values))
    .reset_index())
以下代码可用于创建示例数据帧:

import collections
import datetime
import pandas as pd
import numpy as np

data = {
    'col1_data': ['A1', 'A1'],
    'col2_data': [[{"scenario": 1, "scenario_name": "Test", "value": "100"}], [{"scenario": 1, "scenario_name": "Test1", "value": "10"}, {"scenario": 2, "scenario_name": "Test2", "value": "500"}]]
}

df = pd.DataFrame(data)

with pd.option_context('display.max_colwidth', 1000):  # more options can be specified also
    print(df)
所以我需要对col1_数据进行分组,col2_数据应该合并为json,如上所示

更新2:

f = (df
    .groupby('col1_data')['col2_data']
    .apply(lambda x: np.concatenate(x.values))
    .reset_index())
该解决方案适用于上述数据集。 但是,当我在col1_数据中有两个唯一的值时,它就不起作用了

data = {
    'col1_data': ['A1', 'A1', 'A2', 'A2'],
    'col2_data': [[{"scenario": 1, "scenario_name": "Test", "value": "100"}], [{"scenario": 1, "scenario_name": "Test1", "value": "10"}, {"scenario": 2, "scenario_name": "Test2", "value": "500"}],[{"scenario": 1, "scenario_name": "Test", "value": "10"}], [{"scenario": 1, "scenario_name": "Test1", "value": "110"}, {"scenario": 2, "scenario_name": "Test2", "value": "1500"}]]
}

df = pd.DataFrame(data)
DF的输出:

  col1_data  \
0        A1   
1        A1   
2        A2   
3        A2   

                                                                                                                 col2_data  
0                                                               [{'scenario': 1, 'scenario_name': 'Test', 'value': '100'}]  
1    [{'scenario': 1, 'scenario_name': 'Test1', 'value': '10'}, {'scenario': 2, 'scenario_name': 'Test2', 'value': '500'}]  
2                                                                [{'scenario': 1, 'scenario_name': 'Test', 'value': '10'}]  
3  [{'scenario': 1, 'scenario_name': 'Test1', 'value': '110'}, {'scenario': 2, 'scenario_name': 'Test2', 'value': '1500'}]  
现在,当我运行相同的函数时,我得到以下错误:

df = (df
     .groupby('col1_data')['col2_data']
     .apply(lambda x: np.concatenate(x).tolist())
     .reset_index())
错误:

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
/usr/local/lib64/python3.6/site-packages/pandas/core/groupby/groupby.py in apply(self, func, *args, **kwargs)
    724             try:
--> 725                 result = self._python_apply_general(f)
    726             except Exception:

/usr/local/lib64/python3.6/site-packages/pandas/core/groupby/groupby.py in _python_apply_general(self, f)
    741     def _python_apply_general(self, f):
--> 742         keys, values, mutated = self.grouper.apply(f, self._selected_obj, self.axis)
    743 

/usr/local/lib64/python3.6/site-packages/pandas/core/groupby/ops.py in apply(self, f, data, axis)
    236             group_axes = _get_axes(group)
--> 237             res = f(group)
    238             if not _is_indexed_like(res, group_axes):

<ipython-input-109-61a2e6a29020> in <lambda>(x)
      6      .groupby('col1_data')['col2_data']
----> 7      .apply(lambda x: np.concatenate(x).tolist())
      8      .reset_index())

<__array_function__ internals> in concatenate(*args, **kwargs)

/usr/local/lib64/python3.6/site-packages/pandas/core/series.py in __getitem__(self, key)
   1067         try:
-> 1068             result = self.index.get_value(self, key)
   1069 

/usr/local/lib64/python3.6/site-packages/pandas/core/indexes/base.py in get_value(self, series, key)
   4729         try:
-> 4730             return self._engine.get_value(s, k, tz=getattr(series.dtype, "tz", None))
   4731         except KeyError as e1:

pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_value()

pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_value()

pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()

pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.Int64HashTable.get_item()

pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.Int64HashTable.get_item()

KeyError: 0
---------------------------------------------------------------------------
KeyError回溯(最近一次呼叫最后一次)
/应用中的usr/local/lib64/python3.6/site-packages/pandas/core/groupby/groupby.py(self、func、*args、**kwargs)
724尝试:
-->725结果=self.\u python\u apply\u general(f)
726例外情况除外:
/usr/local/lib64/python3.6/site-packages/pandas/core/groupby/groupby.py in_python_apply_general(self,f)
741定义python应用常规(自我,f):
-->742个键,值,mutated=self.grouper.apply(f,self.\u selected\u obj,self.axis)
743
/应用中的usr/local/lib64/python3.6/site-packages/pandas/core/groupby/ops.py(self、f、data、axis)
236组_轴=_获取_轴(组)
-->237 res=f(组)
238如果不是,则与索引类似(res,组轴):
in(x)
6.groupby('col1\u data')['col2\u data']
---->7.应用(lambda x:np.concatenate(x.tolist())
8.重置索引()
串联(*args,**kwargs)
/usr/local/lib64/python3.6/site-packages/pandas/core/series.py in_u___getitem_u__(self,key)
1067尝试:
->1068结果=self.index.get_值(self,key)
1069
/获取值(self、series、key)中的usr/local/lib64/python3.6/site-packages/pandas/core/index/base.py
4729尝试:
->4730返回self._engine.get_值(s,k,tz=getattr(series.dtype,“tz”,None))
4731除键错误为e1外:
pandas/_libs/index.pyx在pandas中。_libs.index.IndexEngine.get_value()
pandas/_libs/index.pyx在pandas中。_libs.index.IndexEngine.get_value()
pandas/_libs/index.pyx在pandas中。_libs.index.IndexEngine.get_loc()
pandas/_libs/hashtable_class_helper.pxi在pandas._libs.hashtable.Int64HashTable.get_item()中
pandas/_libs/hashtable_class_helper.pxi在pandas._libs.hashtable.Int64HashTable.get_item()中
关键错误:0

知道这里出了什么问题吗?

这里有一种方法可以尝试:

import numpy as np

f = (df
     .groupby('col1_data')['col2_data']
     .apply(lambda x: np.concatenate(x).tolist())
     .reset_index())

 col1_data                                          col2_data
0        A1  [{'scenario': 1, 'scenario_name': 'Test', 'val...
解决方案二:

f = (df
    .groupby('col1_data')['col2_data']
    .apply(lambda x: np.concatenate(x.values))
    .reset_index())
你可以试试这个:

new_dat = {col:[] for col in df.columns}
for key,val in df.groupby('col1_data'):
    new_dat['col1_data'] += [key]
    new_dat['col2_data'] += [[dic for lst in val['col2_data'] for dic in lst]]
new_df_1 = pd.DataFrame(new_dat)

col1_data                                          col2_data
0        A1  [{'scenario': 1, 'scenario_name': 'Test', 'val...
1        A2  [{'scenario': 1, 'scenario_name': 'Test', 'val...
或者与@YOLO的回答风格相同:

new_df_2 = (df
     .groupby('col1_data')['col2_data']
     .apply(lambda x: [dic for lst in x for dic in lst])
     .reset_index())

 col1_data                                          col2_data
0        A1  [{'scenario': 1, 'scenario_name': 'Test', 'val...
1        A2  [{'scenario': 1, 'scenario_name': 'Test', 'val...

如果你制作了你的代码,它将帮助人们回答你的问题。当然,它是更大代码的一部分,但让我尽快尝试一些可以帮助你的东西。我将相应地更新我的问题。谢谢,再次谢谢。它适用于我的示例数据,我将尝试我的实际数据,其中有很多列。然而,当我看到pandas的groupby文档时,在列列表之后的方括号中看不到任何内容。基本上,groupby([cols列表]['col2_数据]];这意味着什么?在groupby和apply之间,我们给出了json列,我需要在其上用方括号进行聚合,这意味着什么呢?嗨@YOLO,请查看第二次更新。如果我给col1_数据赋予更多的唯一值,则会失败。知道它为什么会失败吗?@Mihir它之所以失败,是因为
np.concatenate
接收到一个序列作为输入,而它应该是一个数组,
.values
会解决这个问题。