我正在使用 Pandas groupby 并申请从一个包含 1.5 亿行的 DataFrame 和以下列:

Id  Created     Item    Stock   Price
1   2019-01-01  Item 1  200     10
1   2019-01-01  Item 2  100     15
2   2019-01-01  Item 1  200     10

一个包含 220 万条记录的列表,如下所示:

[{
  "Id": 1,
  "Created": "2019-01-01",
  "Items": [
    {"Item":"Item 1", "Stock": 200, "Price": 10},
    {"Item":"Item 2", "Stock": 100, "Price": 5}
    ]
},
{
  "Id": 2,
  "Created": "2019-01-01",
  "Items": [
    {"Item":"Item 1", "Stock": 200, "Price": 10}
    ]
}]

主要使用这行代码:

df.groupby(['Id', 'Created']).apply(lambda x: x[['Item', 'Stock', 'Price']].to_dict(orient='records'))

这需要相当长的时间,据我所知,像这样的操作对于熊猫来说是很繁重的。 有没有一种非熊猫的方式来完成同样的事情,但性能更好?

编辑:操作需要 55 分钟,我在 AWS 中使用 ScriptProcessor,它让我指定我想要的电量。

编辑 2 :所以使用 artonas 解决方案我越来越接近:这就是我现在设法生产的:

defaultdict(<function __main__.<lambda>()>,
            {'1': defaultdict(list,
                         {'Id': '1',
                          'Created':'2019-01-01',
                          'Items': [{'Item': Item2, 'Stock': 100, 'Price': 15},
                                    {'Item': Item1, 'Stock': 200, 'Price': 10}]
                         })
            },
           {'2': defaultdict(list,
                         {'Id': '2',
                          'Created':'2019-01-01',
                          'Items': [{'Item': Item1, 'Stock': 200, 'Price': 10}]
                         })
            },

但是如何从上面到这个呢?

[{
  "Id": 1,
  "Created": "2019-01-01",
  "Items": [
    {"Item":"Item 1", "Stock": 200, "Price": 10},
    {"Item":"Item 2", "Stock": 100, "Price": 5}
    ]
},
{
  "Id": 2,
  "Created": "2019-01-01",
  "Items": [
    {"Item":"Item 1", "Stock": 200, "Price": 10}
    ]
}]

基本上,我只对所有记录的“defaultdict(list,”之后的部分感兴趣。我需要将它放在一个不依赖于 Id 作为键的列表中。

编辑 3 :上次更新包含我的生产数据集的结果。 通过 artona 提供的公认答案,我设法从55分钟缩短到7 (!) 分钟。 并且没有对我的代码进行任何重大更改。 Phung Duy Phong 提供的解决方案花了我 55 分钟到 17 分钟,也不错。

#1楼 票数:1

如果数据框排序清晰,这意味着同一对( IdCreated )的所有行都是连续的,您可以简单地迭代它们。 但是由于迭代数据帧很昂贵,因为 Pandas 必须为每一行构建一个新系列,所以我会直接迭代底层的 numpy 数组。

代码可以是:

records = []
Id = None

for i in range(len(df)):
    if df['Id'].values[i] != Id or df['Created'].values[i] != created:
        items = []
        Id = df['Id'].values[i]
        created = df['Created'].values[i]
        records.append({'Id': Id, 'Created': created,
                'Items': items})

    items.append({x: df[x].values[i]
              for x in ['Item', 'Stock', 'Price']})

如果最初未对数据进行排序,则可以尝试使用 Pandas 对数据框进行排序,然后使用上面的代码

#2楼 票数:1 已采纳

使用 collections.defaultdict 和 itertuples。 它只遍历行一次。

In [105]: %timeit df.groupby(['Id', 'Created']).apply(lambda x: x[['Item', 'Stock', 'Price']].to_dict(orient='records'))
10.1 s ± 44.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [107]:from collections import defaultdict
     ...:def create_dict():
     ...:     dict_ids = defaultdict(lambda : defaultdict(list))
     ...:     for row in df.itertuples():
     ...:          dict_ids[row.Id][row.Created].append({"Item": row.Item, "Stock": row.Stock, "Price": row.Price})
     ...:     list_of_dicts = [{"Id":key_id, "Created":key_created, "Items": values} for key_id, value_id in dict_ids.items() for key_created, values in value_id.items()]
     ...:     return list_of_dicts

In [108]: %timeit create_dict()
4.58 s ± 417 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

#3楼 票数:0

尝试以下操作:

df['Items'] = df.loc[:, ['X', 'Y', 'Z']].to_dict(orient='records')
df.groupby(['ID', 'CREATED'])['Items'].apply(list).reset_index().to_dict(orient='records')

  ask by Josef translate from so

未解决问题?本站智能推荐:

1回复

Groupby和转换Pandas

示例 DF: 示例 DF: 条件: Group by index ,然后在A列上应用pandas分位数切割,如果有错误,则在mean(col A and col C)上应用分位数切割 代码: 操作: 预期操作: 关于错误的任何建议都会很棒。 我尝试用transform代替apply但这给了我一个错
1回复

python-用groupby填充pandas

我正在尝试向前填充缺失的行以完成数据集中缺失的时间序列行。 数据集的规模很大。 超过 1 亿行。 原始源数据集如下所示。 所需的输出如下 我需要对col2和col3进行分组,以填充col1中每个组合的缺失时间序列行。 目前,我有以下代码可以正常工作,但由于 for 循环而速度非常慢。 有什么方法可以
1回复

应用.groupby()争论后,在熊猫数据框中用NaN替换离群值

我想在应用groupby函数后使用列变量的标准偏差从熊猫数据框中删除离群值。 这是我的数据框: 我想先按“扬声器”对数据框进行分组,然后删除“ ARI”,“ Flesch”和“ Kincaid”值,这些值与特定功能的得分平均值相差超过3个标准差而定义为离群值。 如果可以的话,请告诉我
4回复

Pandas中的Groupby,map和sum导致NaN

数据每个ID多行 期望的输出 对于每个ID,(SUM(Value1))*(Value2)。 在这种情况下,对于ID1,它将是4 * 0 = 0。 我希望将结果放回原始表中,如下所示 我试过这个..但是我在输出表中得到了NaN ..
1回复

具有最大聚合性能的Pandasgroupby函数很慢。groupby性能提升

我有一个大约有 16,000 行的数据框,我正在执行一列的最大聚合并将其按另一列分组。 需要 1.97 秒。 我想提高它的性能。 请求您建议使用 numpy 或矢量化。 数据类型两列都是对象。
2回复

使用groupby将重复值替换为NaN

数据集(MWE) 我试图在location上使用groupby()时用 NaN 替换列 { people_vaccinated,people_fully_vaccinated,people_vaccinated_per_hundred } 中的重复项。 我在网上尝试了一些解决方案,但无法让它们为我工
1回复

GroupBy索引和列然后转换Pandas中的选定列

我有一个示例 DF: 操作: 我正在尝试根据 2 个条件转换此 DF: 知识产权: 代码: 操作: 预期操作: 我不明白为什么我会得到NANs 。 任何建议都会很棒。
1回复

如何在Pandas中为每组应用r2_score

我有一个看起来像这样的数据框: 输出: 我正在尝试使用如下模式生成一个新的 DataFrame: 其中 R2 分数是该 item_id 的 R2 值。 我写了以下代码: 虽然这适用于这个小数据框。 但是,我需要为包含 2000 多个组的更大的数据帧运行此操作,大约 5000000 行,并且我看到不一