【问题标题】:Join multiple CSV files by using python pandas使用 python pandas 加入多个 CSV 文件
【发布时间】:2018-06-05 12:09:24
【问题描述】:

我正在尝试使用 python pandas 从多个 csv 文件创建一个 CSV 文件。

accreditation.csv:-

"pid","accreditation_body","score"
"25799","TAAC","4.5"
"25796","TAAC","5.6"
"25798","DAAC","5.7"

ref_university:-

"id","pid","survery_year","end_year"
"1","25799","2018","2018"
"2","25797","2016","2018"

我想通过阅读table_structure.csv 的指令来创建一个新表。我想加入两个表并重写 accreditation.csvREFERENCES ref_university(id, survey_year)ref_university.csv 连接并通过匹配 pid 列值插入 idsurvery_year 列值。

table_structure.csv:-

table_name,attribute_name,attribute_type,Description
,,,
accreditation,accreditation_body,varchar,
,grading,varchar,
,pid,int4, "REFERENCES ref_university(id, survey_year)"
,score,float8,

修改后的 CSV 文件应如下所示,

accreditation.csv :-

"accreditation_body","grading","pid","id","survery_year","score"
"TAAC","","25799","1","2018","2018","4.5"
"TAAC","","25797","2","2016","2018","5.6"
"DAAC","","25798","","","","5.7"

我可以在 panda 中读取 csv

df = pd.read_csv("accreditation.csv")

但是,阅读 REFERENCES 指令并选择列值的推荐方法是什么。如果没有值,则该列应为空白。 我们不能在熊猫功能中硬核pid。我们必须阅读table_structure.csv 并匹配是否有参考,然后调用提到的列。它不应该被合并,只应该添加特定的列。

【问题讨论】:

    标签: python pandas csv join


    【解决方案1】:

    动态解决方案是可能的,但不是那么容易:

    df = pd.read_csv("table_structure.csv")
    
    #remove only NaNs rows
    df = df.dropna(how='all')
    #repalce NaNs by forward filling
    df['table_name'] = df['table_name'].ffill()
    
    #create for each table_name one row
    df = (df.dropna(subset=['Description'])
           .join(df.groupby('table_name')['attribute_name'].apply(list)
                  .rename('cols'), 'table_name'))
    
    #get name of DataFrame and new columns names
    df['df1'] = df['Description'].str.extract('REFERENCES\s*(.*)\s*\(')
    df['new_cols'] = df['Description'].str.extract('\(\s*(.*)\s*\)')
    df['new_cols'] = df['new_cols'].str.split(', ')
    #remove unnecessary columns
    df = df.drop(['attribute_type','Description'], axis=1).set_index('table_name')
    print (df)
    table_name                                                                
    accreditation            pid  [accreditation_body, grading, pid, score]   
    
                              df1           new_cols  
    table_name                                        
    accreditation  ref_university  [id, survey_year]  
    
    #for select by named create dictioanry of DataFrames
    data = {'accreditation' : pd.read_csv("accreditation.csv"), 
            'ref_university': pd.read_csv("ref_university.csv")}
    

    #seelct by index
    v = df.loc['accreditation']
    print (v)
    attribute_name                                          pid
    cols              [accreditation_body, grading, pid, score]
    df1                                          ref_university
    new_cols                                  [id, survey_year]
    Name: accreditation, dtype: object
    

    按字典和Seriesv选择

    df = pd.merge(data[v.name], 
                   data[v['df1']][v['new_cols'] + [v['attribute_name']]], 
                   on=v['attribute_name'], 
                   how='left')
    

    转换为:

    df = pd.merge(data['accreditation'], 
                   data['ref_university'][['id', 'survey_year'] + ['pid']], 
                   on='pid', 
                   how='left')
    

    然后返回:

    print (df)
         pid accreditation_body  score   id  survey_year
    0  25799               TAAC    4.5  1.0       2018.0
    1  25796               TAAC    5.6  NaN          NaN
    2  25798               DAAC    5.7  NaN          NaN
    

    最后按unionreindex添加新列:

    df = df.reindex(columns=df.columns.union(v['cols']))
    print (df)
      accreditation_body  grading   id    pid  score  survey_year
    0               TAAC      NaN  1.0  25799    4.5       2018.0
    1               TAAC      NaN  NaN  25796    5.6          NaN
    2               DAAC      NaN  NaN  25798    5.7          NaN
    

    【讨论】:

    • 我不能硬核 pid。我们必须读取 table_structure.csv 并匹配是否有引用然后调用该列。
    • 另外,在新的 accreditation.csv 中,有一个新的列分级。此列中的值应为空
    • @DineshAhuja - 添加了动态合并的解决方案。
    • 看起来不错。但是,我有多个 csv 文件,并且 table_structure.csv 中也有多行。如果有“REFERENCES something”,那么它应该自动输入“something.csv”,我们不能手动使用列名,因为它是一个有多个列的大文件。
    • @DineshAhuja - 很难创建通用解决方案...此解决方案仅适用于 2 个 DataFrame。但是如果添加minimal, complete, and verifiable example 是有可能的。还要在Description 中添加所有可能的组合,但同样,请努力。
    猜你喜欢
    • 2018-06-11
    • 2015-10-25
    • 2015-05-23
    • 1970-01-01
    • 2017-07-15
    • 2021-07-25
    • 1970-01-01
    • 2019-03-24
    • 1970-01-01
    相关资源
    最近更新 更多