Python:重新构建数据框架,并使用预定义行重新组合特定列中的数据

2024-05-26 21:51:05 发布

您现在位置:Python中文网/ 问答频道 /正文

假设这个数据框架有四列:“名称”、“值”、“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之前,我希望以不同的方式表示该数据。我想将“Name”列中的重复项与“values”和“Ccy”中的associates值进行分组。我希望列“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

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

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

任何人都可以帮助我

多谢各位


Tags: 数据namecitydfagevaluegroupeur
2条回答

您只需执行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]

您可以使用以下命令。有关每个步骤,请参见代码中的注释:

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”,“German”更改为“GER”,使用reset_index(drop=True),等等

相关问题 更多 >

    热门问题