如何获取多行并将其中一些转换为列

时间:2014-02-13 03:20:22

标签: python pandas dataset

我有以下数据集:

QuestionID  RowID       ColID       MenuID  SourceRowID  SourceColumnID  SourceVariationID  ResponseCount  
----------  ----------  ----------  ------  -----------  --------------  -----------------  -------------  
316923119   3029903189  3029903193  0       3029903177   3029903181      0                  773            
316923119   3029903189  3029903193  0       3029903177   3029903182      0                  788            
316923119   3029903189  3029903193  0       3029903177   3029903183      0                  778            
316923119   3029903189  3029903193  0       3029903177   3029903184      0                  803            
316923119   3029903189  3029903194  0       3029903177   3029903181      0                  766            
316923119   3029903189  3029903194  0       3029903177   3029903182      0                  799            
316923119   3029903189  3029903194  0       3029903177   3029903183      0                  782
316923119   3029903189  3029903194  0       3029903177   3029903184      0                  773

我想将其转换为此数据集:

QuestionID  RowID       ColumnID    MenuID  3029903181  3029903182  3029903183  3029903184  ResponseCount  
----------  ----------  ----------  ------  -------     -------     -------      -------    -------------         
316923119   3029903189  3029903193   0        773        788          778         803          3142          
316923119   3029903189  3029903194   0        766        799          782         773          3120  

这些在Python中表示为:

 [
  {
    'QuestionID': 316923119, 
    'RowID': 3029903189, 
    'ColID': 3029903193, 
    'SourceColumnID': 3029903181,
    'ResponseCount': 773
  },
  {
    'QuestionID': 316923119, 
    'RowID': 3029903189, 
    'ColID': 3029903193, 
    'SourceColumnID': 3029903182,
    'ResponseCount': 788
  },
  {
    'QuestionID': 316923119, 
    'RowID': 3029903189, 
    'ColID': 3029903193, 
    'SourceColumnID': 3029903183,
    'ResponseCount': 778
  },
  {
    'QuestionID': 316923119, 
    'RowID': 3029903189, 
    'ColID': 3029903193, 
    'SourceColumnID': 3029903184,
    'ResponseCount': 803
  },
  {
    'QuestionID': 316923119, 
    'RowID': 3029903189, 
    'ColID': 3029903194, 
    'SourceColumnID': 3029903181,
    'ResponseCount': 766
  },
  {
    'QuestionID': 316923119, 
    'RowID': 3029903189, 
    'ColID': 3029903194, 
    'SourceColumnID': 3029903182,
    'ResponseCount': 799
  },
  {
    'QuestionID': 316923119, 
    'RowID': 3029903189, 
    'ColID': 3029903194, 
    'SourceColumnID': 3029903183,
    'ResponseCount': 782
  },
  {
    'QuestionID': 316923119, 
    'RowID': 3029903189, 
    'ColID': 3029903194, 
    'SourceColumnID': 3029903184,
    'ResponseCount': 773
  },
]

我希望得到:

[
  {
    'QuestionID': 316923119, 
    'RowID': 3029903189, 
    'ColID': 3029903193, 
    '3029903181': 773,
    '3029903182': 788,
    '3029903183': 778,
    '3029903184': 803,
    'ResponseCount': 3142
  },
  {
    'QuestionID': 316923119, 
    'RowID': 3029903189, 
    'ColID': 3029903194, 
    '3029903181': 766,
    '3029903182': 799,
    '3029903183': 782,
    '3029903184': 773,
    'ResponseCount': 3120
  },
]

这里的重大变化是将SourceColumnID行合并到按相同QuestionID,RowID和ColID分组的列中,然后将它们全部合并到一个新列ResponseCount中。

我更愿意将这些数据加载到pandas并使用DataFrame进行转换,但欢迎提出任何建议。

修改

以下TomAugspurger的答案几乎可行:

In [90]: df
Out[90]: 
        ColID  QuestionID  ResponseCount       RowID  SourceColumnID
0  3029903193   316923119            773  3029903189      3029903181
1  3029903193   316923119            788  3029903189      3029903182
2  3029903193   316923119            778  3029903189      3029903183
3  3029903193   316923119            803  3029903189      3029903184
4  3029903194   316923119            766  3029903189      3029903181
5  3029903194   316923119            799  3029903189      3029903182
6  3029903194   316923119            782  3029903189      3029903183
7  3029903194   316923119            773  3029903189      3029903184

[8 rows x 5 columns]

In [91]: counts = df.pivot_table(values='ResponseCount', rows=['ColID', 'QuestionID', 'RowID'], cols='SourceColumnID', aggfunc='sum')

In [92]: counts['ResponseCount'] = counts.sum(1)

In [93]: counts
Out[93]: 
SourceColumnID                    3029903181  3029903182  3029903183  3029903184  ResponseCount
ColID      QuestionID RowID                                                                    
3029903193 316923119  3029903189         773         788         778         803           3142
3029903194 316923119  3029903189         766         799         782         773           3120

[2 rows x 5 columns]

但这不允许我以我需要的方式访问数据,我应该能够获取新列上的计数和访问权限以获取其数量:

counts[0][3029903181]

应该返回773

发现这个工作:

int(counts.iloc[0][3029903181])

1 个答案:

答案 0 :(得分:1)

数据透视表可以解决问题。

In [54]: counts = df.pivot_table(values='ResponseCount',
                                 rows=['ColID', 'QuestionID', 'RowID'],
                                 cols='SourceColumnID', aggfunc='sum')

In [55]: counts
Out[55]: 
SourceColumnID                    3029903181  3029903182  3029903183  \
ColID      QuestionID RowID                                            
3029903193 316923119  3029903189         773         788         778   
3029903194 316923119  3029903189         766         799         782   

SourceColumnID                    3029903184  
ColID      QuestionID RowID                   
3029903193 316923119  3029903189         803  
3029903194 316923119  3029903189         773  

[2 rows x 4 columns]

要获取ResponseCount列,您似乎在对各列进行求和:

In [57]: counts['ResponseCount'] = counts.sum(1)

In [58]: counts
Out[58]: 
SourceColumnID                    3029903181  3029903182  3029903183  \
ColID      QuestionID RowID                                            
3029903193 316923119  3029903189         773         788         778   
3029903194 316923119  3029903189         766         799         782   

SourceColumnID                    3029903184  ResponseCount  
ColID      QuestionID RowID                                  
3029903193 316923119  3029903189         803           3142  
3029903194 316923119  3029903189         773           3120  

[2 rows x 5 columns]

最后,您有一个MenuID列。我已经将它从我的答案中删除了,因为你没有说明它是如何计算的,以及它是否对每个组都是唯一的。您可能需要df.groupby(['ColID', 'QuestionID', 'RowID'])['MenuID'].sum().head(1)之类的内容。