簡體   English   中英

Python 通過公共列合並兩個 CSV

[英]Python merging two CSV by common column

我正在嘗試將兩個 csv 文件與一個公共列合並並將其寫入一個新文件。 例如 product.csv 表將有列

      product_id     name        
       1           Handwash      
       2           Soap          

和 subproduct.csv 將有列

      product_id subproduct_name volume
       1           Dettol         20
       1           Lifebuoy      50
       2           Lux           100

output sales.csv 文件應如下所示:

  product_id        name      subproduct_name     volume 
       1           Handwash      Dettol            20   
       1           Handwash      Lifebuoy          50
       2           Soap           Lux             100 

我試圖創建兩個字典:

with open('product.csv', 'r') as f:
r = csv.reader(f)

dict1 = {row[0]: row[1:] for row in r}

with open('subproduct.csv', 'r') as f:
r = csv.reader(f)

dict2 = {row[0]: row[1:] for row in r}

使用 pandas:

import pandas as pd

products_df = pd.read_csv('product.csv')
subproducts_df = pd.read_csv('subproduct.csv')

sales_df = pd.merge(products_df, subproducts_df, on=0)

與 Pandas 合並

第 1 階段:首先 Pip 安裝 pandas 如果您還沒有這樣做

第 2 階段:創建數據

data1 = {'product_id': [1, 2], 
         'name': ['Handwash', 'Soap'], 
              }
data2  {'product_id': [1, 1, 2], 
'subproduct_name': ['Dettol', 'Lifebuoy', 'Lux'], 'volume' : [20, 50, 100]} 

第 3 階段:將其放入 dataframe

df1 = pd.DataFrame(data1) 
df2 = pd.DataFrame(data2))

第 4 階段:合並數據框

output = pd.merge(df1, df2, how="inner")

與 Pandas 與 CSV 合並

df1=pd.read_csv('product.csv')
df2=pd.read_csv('subproduct.csv')

進行第 4 階段

您可以使用純 python 處理腳本。 它有一個名為csv的強大庫,應該可以解決問題

import csv

with open('product.csv') as csv_produto:
    with open('subproduct.csv') as csv_subproduct:
        produto_reader = list(csv.reader(csv_produto, delimiter=','))
        subproduct_reader = list(csv.reader(csv_subproduct, delimiter=','))
        for p in produto_reader:
            for sp in subproduct_reader:
                if(p[0]==sp[0]):
                    print('{},{},{},{}'.format(p[0], p[1], sp[1], sp[2]))

這是主要思想,現在您可以將 output 保存在 csv 中,並添加一個 header 處理異常。

其他人提出了使用 pandas 的方法。 如果您的文件很大,或者您需要經常執行此操作,您應該考慮它。 但是 csv 模塊在這里就足夠了。

你不能在這里使用普通的字典,因為鍵不是唯一的: subproduct.csv有 2 個不同的行具有相同的 id 1。所以我會使用列表的字典。

我在這里承認,所有鍵都必須存在於 product.csv 中,但某些產品可能沒有關聯的子產品(意味着數據庫措辭中的左外連接)。

所以我將使用:

  • product.csv 的字典,因為我假設 product_id 每個產品都是唯一的
  • subproduct.csv 列表的默認字典,因為單個產品可能有許多子產品
  • 來自 product.csv 的 ID 列表來構建最終文件
  • subproduct.csv 的默認空列表,如果產品沒有子產品
  • 並分別處理標題

代碼可以是:

with open('product.csv') as f:
    r = csv.reader(f)
    header1 = next(r)
    dict1 = {row[0]: row[1:] for row in r}
dict2 = collections.defaultdict(list)
with open('subproduct.csv', 'r') as f:
    r = csv.reader(f)
    header2 = next(r)
    for row in r:
        dict2[row[0]].append(row[1:])

with open('merged.csv', 'w', newline='') as f:
    w = csv.writer(f)
    _ = w.writerow(header1 + header2[1:])
    empty2 = [[] * (len(header2) - 1)]
    for k in sorted(dict1.keys()):
        for row2 in dict2.get(k, empty2):          # accept no subproducts
            _ = w.writerow([k] + dict1[k] + row2)

假設您的 csv 文件是真正的逗號分隔值文件,這給出:

product_id,name,subproduct_name,volume
1,Handwash,Dettol,20
1,Handwash,Lifebuoy,50
2,Soap,Lux,100

請試試這個:

導入 pandas 作為 pd

output = pd.merge(產品,子產品,如何='外部',left_on ='product_id',right_on ='product_id')

它通過 product_id 列連接兩個數據框(product 和 sub_product),這兩者都很常見。 外連接返回與兩個數據幀上的鍵匹配的所有記錄。 即使 = 'inner' 在這種情況下也會起作用

您可以將數據直接讀入 pandas 數據幀,然后合並兩個數據幀:

import pandas as pd

# load data
product = pd.read_csv('product.csv')
subproduct = pd.read_csv('subproduct.csv')

# merge data
merged = pd.merge(product,subproduct)

# write results to csv
merged.to_csv('sales.csv',index=False)

這非常適合您的示例。 根據實際數據的樣子,您可能需要調整 pd.merge 的一些額外 arguments。

編輯:添加了對 csv 部分的寫入

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM