Python:从csv文件读取相同的行-逻辑
我在为csv文件中缺少的行追加数据时遇到问题:我正在为每个客户从csv文件中读取行,并用行所具有的数据追加列表。每个客户都需要具有相同的id,这些id在示例图像中以绿色突出显示。如果下一个客户没有包含所有所需id的行,我仍然需要为这些缺失行的列表添加0值。因此,以黄色突出显示的客户需要在数据列表中附加与绿色相同数量的值 我试图读取每一行并将其id与我创建的所有可能id的列表进行比较,但我总是停留在第一个id上,不确定这是否是再次读取前一行的正确方法,直到它的id等于可能id列表中的id(我这样做是为了将缺少的行的数据添加到列表中)。如果你有什么建议,请告诉我 注意:如果只考虑带id的列,对于这两个客户,我希望列表如下:Python:从csv文件读取相同的行-逻辑,python,Python,我在为csv文件中缺少的行追加数据时遇到问题:我正在为每个客户从csv文件中读取行,并用行所具有的数据追加列表。每个客户都需要具有相同的id,这些id在示例图像中以绿色突出显示。如果下一个客户没有包含所有所需id的行,我仍然需要为这些缺失行的列表添加0值。因此,以黄色突出显示的客户需要在数据列表中附加与绿色相同数量的值 我试图读取每一行并将其id与我创建的所有可能id的列表进行比较,但我总是停留在第一个id上,不确定这是否是再次读取前一行的正确方法,直到它的id等于可能id列表中的id(我这样做
带id的列表=[410、409、408、407、406、405、403、402、**410、409、408、407、406、405、403、402**]
。因此,我正在寻找一种方法——一旦我在黄色的第409行——首先附加第一个需要的id 410,然后才是409,以此类推。相同-在末尾追加两个缺少的ID:403402
代码:
def写入数据(工作簿):
[……]
# 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
#列表。
列表_cust=[]
从某些数据列中列出数量=[]
#获取csv文件中的起始行。
对于范围内的行(worksheet.nrows):
基本id=str(410)
值=工作表。单元格(第1行)。值
start=str(值)
如果基本id[0]==开始[0]:
\u id的\u行的数量=行
#附加第一个id。
第一个\u cust=str(工作表.cell(用于\u id的\u行的num\u,0).value)
列表\客户追加(第一个客户)
#需要清点身份证。
计数=0
#列出每个客户所需的所有id。
#而不是…-图像中的所有ID均为绿色。
所有_id=[…]
#获取数据。
对于范围内的行(worksheet.nrows):
下一个\u id=str(工作表.cell(用于\u id的\u行的num\u,1).value)
cust=str(工作表.cell(用于\u id的\u行的num\u,0).value)
#将id追加到列表中。
列表\客户附加(客户)
#需要为每个客户分隔行。
如果list_cust[len(list_cust)-1]==list_cust[len(list_cust)-2]:
#获取数据:我读取列以获取数据。
#假设我读了第4列到第21列。
对于范围(3,20)中的列数:
#以下是序言:############################
如果下一个id!=所有_id[计数]:
列出数量。追加(0)
如果下一个\u id==所有\u id[计数]:
数量=工作表单元格(行数,列数,列数)。值
列表\数量追加(数量)
#按相反顺序获取下一行。
\u id-=1的\u行\u的数量\u
#id索引的增量计数。
如果list_cust[len(list_cust)-1]==list_cust[len(list_cust)-2]:
#8个可能的id。
如果计数小于7:
计数+=1
其他:
计数=0
考虑以下数据与使用以下包含随机数据列的数据输入的列表理解和循环的数据冲突:
输入数据
# Cust ID Data1 Data2 Data3 Data4 Data5
# 2011 62,404 0.269101238 KPT 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
Python代码
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)
输出数据
# Cust ID Data1 Data2 Data3 Data4 Data5
# 2011 62,404 0.269101238 KPT 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
甚至可以考虑Python第三方模块,如数据分析包;甚至使用Windows内置的Jet/ACE SQL引擎的SQL解决方案也可以直接查询CSV文件
你会注意到下面的和以前的解决方案,在代码< > ID>代码>列中,需要相当多的处理来移除数千个逗号分隔符,因为模块将它们视为字符串第一。如果从原始csv文件中删除此类逗号,则可以减少代码行数
熊猫(在两个数据帧上左合并) PyODBC(仅适用于在两个csv文件上使用左连接的Windows计算机) 输出(适用于上述两种解决方案)用文本描述数据很难理解。你能用前/后(即输入/期望输出)的示例数据来说明吗?并显示当前不期望的结果。那么每个客户都要获得相同的ID集,填写缺失并按下降顺序排序?这就是你所需要的吗?屏幕截图是输入吗?非常感谢你,冻糕,花时间在这上面!这是我需要的输出,我将在我的程序中使用您的逻辑:)我开始使用Python中的大数据和短程序帮助我处理:)因此像pandas这样的模块将非常有用(我知道它,但从未考虑过使用它;需要改变这一点)。非常感谢。
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()