0

假设我有这个包含四列的数据框:“名称”、“值”、“Ccy”和“组”:

import pandas as pd

Name = ['ID', 'Country', 'IBAN','Dan_Age', 'Dan_city', 'Dan_country', 'Dan_sex', 'Dan_Age', 'Dan_country','Dan_sex' , 'Dan_city','Dan_country' ]
Value = ['TAMARA_CO', 'GERMANY','FR56','18', 'Berlin', 'GER', 'M', '22', 'FRA', 'M', 'Madrid', 'ESP']
Ccy = ['','','','EUR','EUR','USD','USD','','CHF', '','DKN','']
Group = ['0','0','0','1','1','1','1','2','2','2','3','3']
df = pd.DataFrame({'Name':Name, 'Value' : Value, 'Ccy' : Ccy,'Group':Group})

print(df)
    
           Name      Value  Ccy Group
0            ID  TAMARA_CO          0
1       Country    GERMANY          0
2          IBAN       FR56          0
3       Dan_Age         18  EUR     1
4      Dan_city     Berlin  EUR     1
5   Dan_country        GER  USD     1
6       Dan_sex          M  USD     1
7       Dan_Age         22          2
8   Dan_country        FRA  CHF     2
9       Dan_sex          M          2
10     Dan_city     Madrid  DKN     3
11  Dan_country        ESP          3
  1. 在将其保存在 csv 中之前,我想以不同的方式表示这些数据。我想将“名称”列中的重复项与“值”和“Ccy”中的关联值分组。我希望将“Value”和“Ccy”列中的数据存储在“Group”列定义的行(索引)中。像这样我不混合数据。

  2. 然后,如果名称在“组”0 中,则表示它是一般数据,所以我希望该“名称”中的所有行都填充相同的值。

所以我想得到这个结果:

   ID_Value  Country_Value  IBAN_Value  Dan_age Dan_age_Ccy  Dan_city_Value Dan_city_Ccy Dan_sex_Value
1  TAMARA    GER            FR56        18      EUR          Berlin         EUR          M
2  TAMARA    GER            FR56        22                                               M
3  TAMARA    GER            FR56                             Madrid         DKN

我找不到如何做第一部分。使用下面的代码,如果我将列删除为空,我不会得到我想要的

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]}')

任何人都可以帮助我!

谢谢

4

2 回答 2

1

您可以使用以下内容。请参阅每个步骤的代码中的注释:

s = df.loc[df['Group'] == '0', 'Name'].tolist() # this variable will be used later according to Condition 2
df['Name'] = pd.Categorical(df['Name'], categories=df['Name'].unique(), ordered=True) #this preserves order before pivoting
df = df.pivot(index='Group', columns='Name') #transforms long-to-wide per expected output
for col in df.columns:
    if col[1] in s: df[col] = df[col].shift().ffill() #Condition 2
df = df.iloc[1:].replace('',np.nan).dropna(axis=1, how='all').fillna('') #dataframe cleanup
df.columns = ['_'.join(col) for col in df.columns.swaplevel()] #column name cleanup
df
Out[1]: 
        ID_Value Country_Value IBAN_Value Dan_Age_Value Dan_city_Value  \
Group                                                                    
1      TAMARA_CO       GERMANY       FR56            18         Berlin   
2      TAMARA_CO       GERMANY       FR56            22                  
3      TAMARA_CO       GERMANY       FR56                       Madrid   

      Dan_country_Value Dan_sex_Value Dan_Age_Ccy Dan_city_Ccy  \
Group                                                            
1                   GER             M         EUR          EUR   
2                   FRA             M                            
3                   ESP                                    DKN   

      Dan_country_Ccy Dan_sex_Ccy  
Group                              
1                 USD         USD  
2                 CHF              
3    

从那里,您可以删除不需要的列,将字符串从“TAMARA_CO”更改为“TAMARA”,将“GERMANY”更改为“GER”,使用reset_index(drop=True)等。

于 2020-10-28T22:35:06.600 回答
1

您只需 3 个步骤即可轻松完成此操作:

  1. 将您的数据框分成两部分:“一般数据”(我们想要作为一个系列)和更具体的数据。现在每个数据框都包含相同种类的信息。
  2. 问题的关键部分:重组数据。你所需要的只是pandas 的 pivot函数。它完全满足您的需求!
  3. 将一般信息和透视数据重新添加到一起。
# Split Data
general = df[df.Group == "0"].set_index("Name")["Value"].copy()
main_df = df[df.Group != "0"]

# Pivot Data
result = main_df.pivot(index="Group", columns=["Name"], 
                       values=["Value", "Ccy"]).fillna("")
result.columns = [f"{c[1]}_{c[0]}" for c in result.columns]

# Create a data frame that has an identical row for each group
general_df = pd.DataFrame([general]*3, index=result.index)
general_df.columns = [c + "_Value" for c in general_df.columns]

# Merge the data back together
result = general_df.merge(result, on="Group")

上面给出的结果没有给出你想要的确切的列顺序,所以你必须手动指定

final_cols = ["ID_Value", "Country_Value", "IBAN_Value",
              "Dan_age_Value", "Dan_Age_Ccy", "Dan_city_Value",
              "Dan_city_Ccy", "Dan_sex_Value"]
result = result[final_cols]
于 2020-10-28T22:36:00.173 回答