首页 > 解决方案 > Python:从熊猫数据框/组重复中重塑演示数据

问题描述

假设我有这个包含三列的数据框:“名称”、“帐户”和“Ccy”。

import pandas as pd

Name = ['Dan', 'Mike', 'Dan', 'Dan', 'Sara', 'Charles', 'Mike', 'Karl']
Account = ['100', '30', '50', '200', '90', '20', '65', '230']
Ccy = ['EUR','EUR','USD','USD','','CHF', '','DKN']
df = pd.DataFrame({'Name':Name, 'Account' : Account, 'Ccy' : Ccy})


    Name    Account Ccy
0   Dan     100     EUR
1   Mike    30      EUR
2   Dan     50      USD
3   Dan     200     USD
4   Sara    90  
5   Charles 20      CHF
6   Mike    65  
7   Karl    230     DKN

我想以不同的方式表示这些数据。我想编写一个脚本来查找列名中的所有重复项,并将它们与不同的帐户重新组合,如果有货币“Ccy”,它会在其旁边添加一个新列,其中包含所有关联的货币。

所以类似的东西:

    Dan Ccy1    Mike    Ccy2    Sara    Charles Ccy3    Karl    Ccy4
0   100 EUR     30      EUR     90      20      CHF     230     DKN
1   50  USD     65                      
2   200 USD     

我真的不知道如何开始!所以我将问题简化为步骤 y 步骤。我尝试使用列表按名称重新组合重复项,但它没有识别重复项。

x_len, y_len = df.shape
new_data = []

for i in range(x_len) :
    
        if df.iloc[i,0] not in new_data :
            print(str(df.iloc[i,0]) + '\t'+ str(df.iloc[i,1])+ '\t' + str(bool(df.iloc[i,0] not in new_data)))
            new_data.append([df.iloc[i,0],df.iloc[i,1]])
            
        
        else: 
            new_data[str(df.iloc[i,0])].append(df.iloc[i,1])

然后我认为使用字典更容易。所以我尝试了这个循环,但有一个错误,也许它不是达到预期最终结果的最佳方式

from collections import defaultdict

dico=defaultdict(list)
x_len, y_len = df.shape

for i in range(x_len) :

    if df.iloc[i,0] not in dico :
        print(str(df.iloc[i,0]) + '\t'+ str(df.iloc[i,1])+ '\t' + str(bool(df.iloc[i,0] not in dico)))
        dico[str(df.iloc[i,0])] = df.iloc[i,1]
        print(dico)
    
    else : 
        dico[df.iloc[i,0]].append(df.iloc[i,1])

如果代码很简单,任何人都知道如何开始或编写代码?谢谢

标签: pythonpandasdataframedictionaryduplicates

解决方案


用于GroupBy.cumcountcounter、reshape byDataFrame.set_indexDataFrame.unstacklast flatten 列名称:

g = df.groupby(['Name']).cumcount()

df = df.set_index([g,'Name']).unstack().sort_index(level=1, axis=1)
df.columns = df.columns.map(lambda x: f'{x[0]}_{x[1]}')
print (df)
  Account_Charles Ccy_Charles Account_Dan Ccy_Dan Account_Karl Ccy_Karl  \
0              20         CHF         100     EUR          230      DKN   
1             NaN         NaN          50     USD          NaN      NaN   
2             NaN         NaN         200     USD          NaN      NaN   

  Account_Mike Ccy_Mike Account_Sara Ccy_Sara  
0           30      EUR           90           
1           65                   NaN      NaN  
2          NaN      NaN          NaN      NaN  

if-else如果需要在列表理解中使用自定义列名称:

g = df.groupby(['Name']).cumcount()

df = df.set_index([g,'Name']).unstack().sort_index(level=1, axis=1)
L = [b if a == 'Account' else f'{a}{i // 2}' for i, (a, b) in enumerate(df.columns)]
df.columns = L
print (df)
  Charles Ccy0  Dan Ccy1 Karl Ccy2 Mike Ccy3 Sara Ccy4
0      20  CHF  100  EUR  230  DKN   30  EUR   90     
1     NaN  NaN   50  USD  NaN  NaN   65       NaN  NaN
2     NaN  NaN  200  USD  NaN  NaN  NaN  NaN  NaN  NaN
    

推荐阅读