将 DataFrame 拆分为来自多列的组字典

Posted

技术标签:

【中文标题】将 DataFrame 拆分为来自多列的组字典【英文标题】:Split DataFrame into a dictionary of groups from multiple columns 【发布时间】:2018-02-02 21:48:29 【问题描述】:

我有一个这样的数据框:

     df = pd.DataFrame(
               'Client':['A','B','C','D','E'],  
               'Revenue':[100,120,50,40,30],  
               'FYoQ':['FY','Q','Q','Q','FY'],  
              'Quarter':[np.nan,1,3,4,np.nan],  
              'Year':[2017,2016,2015,2017,2016]
        )

如何拆分数据框以获得二维字典数据框 ds[year][quarter] 表示每年和每季度。

现在我可以按如下方式制作一维字典:

   years=df['Year'].unique().tolist()  
   mc=elem:pd.DataFrame for elem in years  

  for year in years:  
      mc[year]=df.loc[(df['Year']==year)]  

这样我获得了数据框 mc[2015]、mc[2016] 等的字典。 然后我必须再次对他们每个人应用相同的东西。

我希望对代码进行修改:

  mc=elem:pd.DataFrame for elem in years  

一次创建一个二维(甚至是多维字典),从而可以更快地拆分数据。

【问题讨论】:

【参考方案1】:
from collections import defaultdict

d = defaultdict(dict)
[d[y].setdefault(q, g) for (y, q), g in df.groupby(['Year', 'Quarter'])];
d = dict(d)

for y, v in d.items():
    print(y)
    for q, s in v.items():
        print('    ' + str(q))
        p = s.__repr__()
        p = '\n'.join(['        ' + l for l in p.split('\n')])
        print(p, '\n')

2015
    3.0
          Client FYoQ  Quarter  Revenue  Year
        2      C    Q      3.0       50  2015 

2016
    1.0
          Client FYoQ  Quarter  Revenue  Year
        1      B    Q      1.0      120  2016 

2017
    4.0
          Client FYoQ  Quarter  Revenue  Year
        3      D    Q      4.0       40  2017 

【讨论】:

作为使用说明(给 OP):单级字典比需要两次单独查找的嵌套字典更便于访问。 同意!但是OP确实要求二维。我认为这是 OP 要求的。你的就是 OP 需要的。 谢谢,让我试试这个。看起来你们都同意,另一种解决方案更好/更快。【参考方案2】:

IIUC,您可以使用df.set_index 设置多索引,然后调用df.groupby。然后,在 dict 理解中构建您的字典:

dict_ = i : g for i, g in df.set_index(['Year', 'Quarter']).groupby(level=[0, 1])

for k in dict_:
    print(dict_[k])

             Client FYoQ  Revenue
Year Quarter                     
2016 1.0          B    Q      120


             Client FYoQ  Revenue
Year Quarter                     
2015 3.0          C    Q       50


             Client FYoQ  Revenue
Year Quarter                     
2017 4.0          D    Q       40

键是(year, quarter) 元组,非常易于管理。


要保存到 CSV 文件,最后一个循环需要一个 .to_csv 调用:

for k in dict_:
    label = 'dataQ'.format(map(str, k))
    dict_[k].to_csv(label)

【讨论】:

谢谢,让我试试看。 谢谢这确实有效。我想知道如何修改最后一个 for 循环,以便我可以编写 pd.to_csv 各种生成的文件,这些文件会自动获得名称,如“data2015Q1.csv”、“data2015Q2.csv”、....、“data2016Q4. csv"... @AlhpaDelta 已编辑。你需要.to_csv 它给出了一个错误“IndexError:tuple index out of range”。到目前为止效果很好(谢谢!)。如果我能把它写回来,那就完美了,实际数据是几年零四个季度。

以上是关于将 DataFrame 拆分为来自多列的组字典的主要内容,如果未能解决你的问题,请参考以下文章

R语言将dataframe的某个字符串列拆分为多列实战

将 Spark Dataframe 字符串列拆分为多列

将 Spark Dataframe 字符串列拆分为多列

Pandas使用split函数基于指定分隔符拆分数据列的内容为列表设置参数n控制拆分的次数设置expand参数将拆分结果列表内容转化为多列dataframe并添加到原dataframe中

Pandas使用split函数基于指定分隔符拆分数据列的内容为列表设置expand参数将拆分结果列表内容转化为多列dataframe并添加到原dataframe中drop函数基于数据列名称删除列

将 Pandas 单元格中的列表拆分为多列 [重复]