2017-02-20 14 views
0

csvファイルに欠落している行のデータを追加する際に問題があります。各顧客のcsvファイルから行を読み込み、行にあるデータをリストに追加しています。各顧客は、例のイメージで緑色で強調表示されている同じIDを持つ必要があります。次の顧客が必要なすべてのIDを持つ行を持っていない場合、これらの行のリストに0の値を追加する必要があります。そのため、黄色で強調表示された顧客は、緑色のデータリストと同じ数の値をデータリストに追加する必要があります。Python:csvファイルから同じ行を読み取る - 論理

私は各行を読み込み、そのIDと私が作成したすべてのIDのリストを比較しようとしていますが、最初のIDについていて、これが正しいかどうかはわかりませんidの値がidからリストのidに等しくなるまで(私は行のデータをリストに追加するためにこれを行います)。ご提案があれば教えてください。

注:は、idをして考慮のみの列を取る場合は、これらの2人の顧客のために、私はこのように見えるようにリストをしたいと思います:list_with_ids = [410, 409, 408, 407, 406, 405, 403, 402, **410, 409, 408, 407, 406, 405, 403, 402**]を。だから私は最初に必要なID410を最初に追加し、次に409だけを追加する方法を探しています。 - と同じ端にある2つの不足しているIDを付加します、403 402

コード: デフ書込データ(ワークブック): [...]

# Lists. 
list_cust = [] 
list_quantity = [] # from Some_data columns 

# Get the start row in the csv file. 
for row in range(worksheet.nrows): 
    base_id = str(410) 
    value = worksheet.cell(row, 1).value 
    start = str(value) 
    if base_id [0] == start[0]: 
     num_of_row_for_id = row 

# Append the first id. 
first_cust = str(worksheet.cell(num_of_row_for_id, 0).value) 
list_cust.append(first_cust) 

# Needed to count id's. 
count = 0 

# List with all needed id's for each customer. 
# instead of ... - all ids' in green from the image. 
all_ids = [....] 

# Get data. 
for row in range(worksheet.nrows): 
    next_id = str(worksheet.cell(num_of_row_for_id, 1).value) 
    cust = str(worksheet.cell(num_of_row_for_id, 0).value) 

    # Append id to the list. 
    list_cust.append(cust) 


    # Needed to separate rows for each customer. 
    if list_cust[len(list_cust)-1] == list_cust[len(list_cust)-2]: 

      # Get data: I read columns to get data. 
      # Let's say I read col 4 to 21. 
      for col_num in range(3, 20): 

       # Here is the prolem: ############################ 
       if next_id != all_ids[count]: 
        list_quantity.append(0) 

       if next_id == all_ids[count]: 
        qty = worksheet.cell(num_of_row_for_id, col_num).value 
        list_quantity.append(qty) 

    # Get the next row in reverse order. 
    num_of_row_for_id -= 1 

    # Increment count for id's index. 
    if list_cust[len(list_cust)-1] == list_cust[len(list_cust)-2]: 
     # 8 possible id's. 
     if count < 7: 
      count += 1  
    else: 
     count = 0 
+0

(両方とも上記の解決策のためには)理解するのは難しいです。前/後(すなわち、入力/希望出力)のサンプルデータで説明できますか?現在の望ましくない結果を表示します。 – Parfait

+0

各顧客はIDの同じセットを取得し、ミスを記入し、descendig順にソートする必要がありますか?それだけでいいの?スクリーンショットは入力されていますか? – Parfait

答えて

0

リストの内包と口論次のデータを考えてみましょうランダムデータ列を含む次のデータ入力を使用してループ:

入力データ

# Cust ID  Data1  Data2 Data3  Data4 Data5 
# 2011 62,404 0.2691KPT 0.438881697 UAX 0.963170513 
# 2011 62,405 0.142397746 XYD 0.51668728 PTQ 0.761695425 
# 2011 62,406 0.782342616 QCN 0.259141256 FNX 0.870971924 
# 2011 62,407 0.221750017 EIU 0.358439487 MAN 0.13633062 
# 2011 62,408 0.097509568 CRU 0.410058705 BFK 0.680228327 
# 2011 62,409 0.322871333 LAC 0.489425167 GUX 0.449476844 
# 919 62,403 0.371461633 PUR 0.626146074 KWX 0.525711736 
# 919 62,404 0.384859932 AJZ 0.223408599 JSU 0.914916663 
# 919 62,405 0.020630503 SFY 0.260778598 VUU 0.213559498 
# 919 62,406 0.952425138 EBI 0.59595738 ZYU 0.283794413 
# 919 62,407 0.410368534 BTT 0.252698401 FFY 0.41080646 
# 919 62,408 0.553390336 GMA 0.846309022 BIN 0.049852419 
# 919 62,409 0.193437955 NBB 0.877311494 XQX 0.080656637 

パイソンコード

import csv 

i = 0 
data = [] 
# READ CSV AND CAPTURE HEADERS AND DATA 
with open('Input.csv', 'r') as f:  
    rdr = csv.reader(f)  
    for line in rdr: 
     if i == 0: 
      headers = line 
     else: 
      line[1] = int(line[1].replace(',','')) 
      data.append(line) 
     i += 1 

# CREATE NEEDED LISTS 
cust_list = list(set([i[0] for i in data])) 
id_list = [62402,62403,62404,62405,62406,62407,62408,62409,62410] 

# CAPTURE MISSING IDS BY CUSTOMER 
for c in cust_list: 
    currlist = [d[1] for d in data if d[0] == c] 
    missingids = [i for i in id_list if i not in currlist] 
    for m in missingids: 
     data.append([c, m,'','','','','']) 

# WRITE DATA TO NEW CSV IN SORTED ORDER 
with open('Output.csv', 'w') as f: 
    wtr = csv.writer(f, lineterminator='\n') 
    wtr.writerow(headers) 
    for c in cust_list: 
     for i in sorted(id_list, reverse=True): 
      for d in data: 
       if d[0] == c and d[1] == i: 
        wtr.writerow(d) 

出力データ

Output Data

+0

これに時間を費やしてくれてありがとう、パフェット!これは私が必要とする出力であり、私のプログラムであなたのロジックを使用します:) –

0

ようpandas、データ分析パッケージとしてもPythonのサードパーティのモジュールを検討します。 Windowsの組み込みのJet/ACE SQL EngineはCSVファイルを直接照会できるので、pyodbcを使用したSQLソリューションです。

IDの列にある1000個のカンマ区切りをモジュールが文字列として最初に認識しているため、これを削除するにはかなりの処理が必要です。元のCSVファイルからそのようなカンマを削除すると、コード行を減らすことができます。

パンダ(2つのデータフレームの左マージ付き)

import pandas as pd 

df = pd.read_csv('Input.csv') 

cust_list = df['Cust'].unique() 
id_list = [62402,62403,62404,62405,62406,62407,62408,62409,62410] 

ids = pd.DataFrame({'Cust': [int(c) for i in id_list for c in cust_list], 
        'ID': [int(i) for i in id_list for c in cust_list]}) 

df['ID'] = df['ID'].str.replace(',','').astype(int) 

df = ids.merge(df, on=['Cust', 'ID'], how='left').\ 
       sort_values(['Cust', 'ID'], ascending=[True, False]) 

df.to_csv('Output_pandas.csv', index=False) 

はPyODBC(2つのCSVファイルに参加し、左使用してWindowsマシンでのみ動作します)

import pyodbc 

conn = pyodbc.connect(r'Driver=Microsoft Access Text Driver (*.txt, *.csv);' + \ 
         'DBQ=C:\Path\To\CSV\Files;Extensions=asc,csv,tab,txt;', 
         autocommit=True) 
cur = conn.cursor() 
cust_list = [i[0] for i in cur.execute("SELECT DISTINCT c.Cust FROM Input.csv c")] 
id_list = [62402,62403,62404,62405,62406,62407,62408,62409,62410] 
cur.close() 

with open('ID_list.csv', 'w') as f: 
    wtr = csv.writer(f, lineterminator='\n') 
    wtr.writerow(['Cust', 'ID']) 
    for item in [[int(c),int(i)] for c in cust_list for i in id_list]: 
     wtr.writerow(item)  
i = 0 
with open('Input.csv', 'r') as f1, open('Input_without_commas.csv', 'w') as f2: 
    rdr = csv.reader(f1); wtr = csv.writer(f2, lineterminator='\n')  
    for line in rdr: 
     if i > 0: 
      line[1] = int(line[1].replace(',','')) 
     wtr.writerow(line) 
     i += 1 

strSQL = "SELECT i.Cust, i.ID, c.Data1, c.Data2, c.Data3, c.Data4, c.Data5 " +\ 
     " FROM ID_list.csv i" +\ 
     " LEFT JOIN Input_without_commas.csv c" +\ 
     " ON i.Cust = c.Cust AND i.ID = c.ID" +\ 
     " ORDER BY i.Cust, i.ID DESC" 

cur = conn.cursor() 
with open('Output_sql.csv', 'w') as f: 
    wtr = csv.writer(f, lineterminator='\n') 
    wtr.writerow(['Cust', 'ID', 'Data1', 'Data2', 'Data3', 'Data4', 'Data5'])  
    for i in cur.execute(strSQL):   
     wtr.writerow(i) 

cur.close() 
conn.close() 

出力テキストでデータを記述

CSV Output

+0

私は大きなデータとPythonの短いプログラムを扱うことから始まります。それで、パンダなどのモジュールはとても役に立ちます。それを使用することは考えられませんでした;これを変更する必要があります)。ありがとうございました! –

関連する問題