如何在 Pandas 中创建按索引分组的记录列表?

Posted

技术标签:

【中文标题】如何在 Pandas 中创建按索引分组的记录列表?【英文标题】:How can I create a list of records groupedby index in Pandas? 【发布时间】:2017-12-31 09:43:20 【问题描述】:

我有一个 CSV 记录:

name,credits,email
bob,,test1@foo.com
bob,6.0,test@foo.com
bill,3.0,something_else@a.com
bill,4.0,something@a.com
tammy,5.0,hello@gmail.org

其中name 是索引。因为有多个具有相同名称的记录,我想将整行(减去名称)滚动到一个列表中以创建表单的 JSON:


  "bob": [
       "credits": null, "email": "test1@foo.com",
       "credits": 6.0, "email": "test@foo.com" 
  ], 
  // ...

我目前的解决方案有点笨拙,因为它似乎只使用 pandas 作为读取 CSV 的工具,但它仍然会生成我预期的 JSONish 输出:

#!/usr/bin/env python3

import io
import pandas as pd
from pprint import pprint
from collections import defaultdict

def read_data():
    s = """name,credits,email
bob,,test1@foo.com
bob,6.0,test@foo.com
bill,3.0,something_else@a.com
bill,4.0,something@a.com
tammy,5.0,hello@gmail.org
"""

    data = io.StringIO(s)
    return pd.read_csv(data)

if __name__ == "__main__":
    df = read_data()
    columns = df.columns
    index_name = "name"
    print(df.head())

    records = defaultdict(list)

    name_index = list(columns.values).index(index_name)
    columns_without_index = [column for i, column in enumerate(columns) if i != name_index]

    for record in df.values:
        name = record[name_index]
        record_without_index = [field for i, field in enumerate(record) if i != name_index]
        remaining_record = k: v for k, v in zip(columns_without_index, record_without_index)
        records[name].append(remaining_record)
    pprint(dict(records))

有没有办法在原生 pandas(和 numpy)中做同样的事情?

【问题讨论】:

【参考方案1】:

这是你想要的吗?

cols = df.columns.drop('name').tolist()

或按照@jezrael 的建议:

cols = df.columns.difference(['name']) 

然后:

s = df.groupby('name')[cols].apply(lambda x: x.to_dict('r')).to_json()

让我们好好打印吧:

In [45]: print(json.dumps(json.loads(s), indent=2))

  "bill": [
    
      "credits": 3.0,
      "email": "something_else@a.com"
    ,
    
      "credits": 4.0,
      "email": "something@a.com"
    
  ],
  "bob": [
    
      "credits": null,
      "email": "test1@foo.com"
    ,
    
      "credits": 6.0,
      "email": "test@foo.com"
    
  ],
  "tammy": [
    
      "credits": 5.0,
      "email": "hello@gmail.org"
    
  ]

【讨论】:

差不多!如果我不需要显式列出groupby 之后的列,那就太好了,但我认为这很简单。 完美!非常感谢您的帮助! 和更好的cols = df.columns.difference(['name'])

以上是关于如何在 Pandas 中创建按索引分组的记录列表?的主要内容,如果未能解决你的问题,请参考以下文章

Python Pandas 索引排序/分组/日期时间

Pandas DataFrame 分组索引匹配列表 - 索引分别小于 list[i+1] 和大于 list[i]

pandas使用groupby函数基于指定分组变量对dataframe数据进行分组使用groups属性获取每个分组的样本对应的在原dataframe中的行索引位置列表

我需要从 pandas DataFrame 对象中创建一个 python 列表对象或任何对象,对来自不同行的值进行分组

如何创建一个新的 pandas 列,该列是索引范围中每个值的列表,不包括行值

如何通过分组索引访问 pandas groupby 数据框?