【问题标题】:How to fill data from similar columns into a particular column(pandas)?如何将相似列中的数据填充到特定列(熊猫)中?
【发布时间】:2021-04-06 18:55:13
【问题描述】:

我有一个转换文件的脚本。

import pandas as pd

df = pd.read_csv("sample1.csv")
final_df = df.reindex(['id','name','email'],axis=1)
final_df.to_csv("output.csv", index = False)

sample1.csv

|name|email|id|
|--|  -- |  -- | 

输出.csv

|id|name|email|
|--|  -- |  -- | 

现在,如果其他示例文件的格式如下所示,如何以与 output.csv 相同的格式排列它们

sample2.csv

|id|first name |email address|
 |--|  -- |  -- | 
 |1 | Sta |sta@example.com|
 |2 |Danny|dany@example.com|
 |3 |Elle |elle@example.com|

sample3.csv

|id|initial name |email id|
 |--|  -- |  -- | 
 |1 | Ricky|ricky@example.com|
 |2 |Sham|sham@example.com|
 |3 |Mark|@example.com|

sample4.csv

 | id |alias|contact|
 |-- |  -- |  -- | 
 | 1 | Ricky|ricky@example.com|
 |2 |Sham|sham@example.com|
 |3 |Mark|@example.com|

我想转换这些文件并将它们放在输出文件的列中。例如,名字、首字母、别名指的是姓名(都表示相同),而电子邮件地址、电子邮件ID和联系人应指电子邮件。示例文件中的列顺序可以是随机的。

这个案例的基本说明是:

switch(headerfields[i])
{ 
   case "firstname":
   case "initial name":
   case "alias":
      name = i;

}

有在 Pandas 中执行此操作的想法吗?

【问题讨论】:

  • 每个数据帧中的顺序是否相同?
  • 不,可以不同。实际上,我想创建一个带有新标题的新输出文件,这些字段应该参考。

标签: python python-3.x pandas dataframe numpy


【解决方案1】:

选择目标列,然后追加到目标 DataFrame。

dfn = pd.DataFrame(columns=['id', 'name', 'email'])
for df in [df1, df2, df3]:
    # select columns
    cond_list = [
                df.columns =='id', 
                df.columns.str.contains('name|alias', na=False),
                df.columns.str.contains('email|contact', na=False)
    ]
    cols = [df.columns[cond][0] for cond in cond_list]
    print(cols)
    dfn = dfn.append(pd.DataFrame(df[cols].values, columns=dfn.columns))

输出:

['id', 'first name', 'email address']
['id', 'initial name', 'email id']
['id', 'alias', 'contact']

dfn:

  id   name              email
0  1    Sta    sta@example.com
1  2  Danny   dany@example.com
2  3   Elle   elle@example.com
0  1  Ricky  ricky@example.com
1  2   Sham   sham@example.com
2  3   Mark       @example.com
0  1  Ricky  ricky@example.com
1  2   Sham   sham@example.com
2  3   Mark       @example.com

测试数据:

df_str = '''
id  "first name"    "email address"
1   Sta sta@example.com
2   Danny   dany@example.com
3   Elle    elle@example.com
'''
df1 = pd.read_csv(io.StringIO(df_str.strip()), sep='\s+', index_col=False)

df_str = '''
id  "initial name"  "email id"
1   Ricky   ricky@example.com
2   Sham    sham@example.com
3   Mark    @example.com

'''
df2 = pd.read_csv(io.StringIO(df_str.strip()), sep='\s+', index_col=False)

df_str = '''
id  alias   contact
1   Ricky   ricky@example.com
2   Sham    sham@example.com
3   Mark    @example.com
'''
df3 = pd.read_csv(io.StringIO(df_str.strip()), sep='\s+', index_col=False)


df1['1'] = 1
df2['2'] = 2
df3['3'] = 3

df1.sort_index(axis=1, inplace=True)
df2.sort_index(axis=1, inplace=True)
df3.sort_index(axis=1, inplace=True)

【讨论】:

    【解决方案2】:

    不是最干净的解决方案,但您可以针对某些字符串/数字测试每个数据帧的前 5 行,并假设这是您的目标列。

    import numpy as np
    import pandas as pd
    def rename_and_merge_dfs(dfs : list) -> pd.DataFrame:
        new_dfs = []
        for frame in dfs:
        
            id_col = frame.head(5).select_dtypes(np.number).columns[0]
            email = frame.columns[frame.head(5).replace('[^@]','',regex=True).eq('@').all()][0]
            name = list(set(frame.columns) - set([id_col, email]))[0]
    
            frame = frame.rename(columns={id_col : 'id', email : 'email', name : 'name'})
            new_dfs.append(frame)
            
        return pd.concat(new_dfs)
    

    final = rename_and_merge_dfs([df3,df2,df1])
    
    print(final)
    
       id    name              email
    1   1   Ricky  ricky@example.com
    2   2    Sham   sham@example.com
    3   3    Mark       @example.com
    0   1   Ricky  ricky@example.com
    1   2    Sham   sham@example.com
    2   3    Mark       @example.com
    0   1     Sta    sta@example.com
    1   2   Danny   dany@example.com
    2   3    Elle   elle@example.com
    

    【讨论】:

    • 我不想连接那些列
    • 对,刚刚看到你的编辑@AtomStore 代码非常简单,你可以编辑它以获得你的输出吗?
    【解决方案3】:

    这解决了我的问题。

    import pandas as pd
    sample1 = pd.read_csv('sample1.csv')
    
    def mapping(df):
        for column_name, column in df.transpose().iterrows():
            df.rename(columns ={'first name' : 'FNAME', 'email address': 'EMAIL'}, inplace = True)
            df.rename(columns ={'alias' : 'FNAME', 'contact': 'EMAIL'}, inplace = True)
            df.rename(columns ={'initial name' : 'FNAME', 'emailid': 'EMAIL'}, inplace = True)
    
    mapping(sample1)
    

    【讨论】:

    • 不知道你为什么在函数中使用for循环。并且映射函数与df.rename(columns = {'first name' : 'FNAME', 'email address': 'EMAIL','alias' : 'FNAME', 'contact': 'EMAIL', 'initial name' : 'FNAME', 'emailid': 'EMAIL'}, inplace = True)相同
    猜你喜欢
    • 1970-01-01
    • 2018-06-20
    • 2020-12-27
    • 2021-09-26
    • 1970-01-01
    • 1970-01-01
    • 2019-05-11
    • 2020-11-19
    • 1970-01-01
    相关资源
    最近更新 更多