Python怎么对把多个CSV文件中的两列进行合并,重复的名字的成绩相加

因为每个表的人数不是固定的,所以要把每个表中的账户和成绩读取出来相加,后面再进行核算。文件是CSV格式,表会有多个表,但每个班读取的数据只有两列
当前两个表

img


img


想做成的表

img

目前想法是读取表中数据,再把两列数据分别存储在不同的列表里,再新建文件把他们放进去,但问题是CSV包不能写列操作,写完前面的,后面就写不了,卡在这了。

img

content.remove('zhanghao')
context.remove('zhanghao')
consocre1.remove('chengji')
consocre2.remove('chengji')
filelen1=len(content)
filelen2=len(content)
print(content)
print(consocre1)
print(context)
print(consocre2)
print("-----------------------")
#存放两边相同元素
ting=[]
#找两个表相同的名字
for i in content:
    for j in context:
         if i==j:
             ting.append(i)


import pandas as pd

df1 = pd.read_csv("1111.csv", header=0)
df2 = pd.read_csv("2222.csv", header=0)
print(df1.head())
print(df2.head())
df3 = pd.concat([df1, df2], axis=0)
df3.groupby('name').sum().to_csv("3333.csv")
import csv

def main():
    dic = dict()
    # import os
    # file_li = os.listdir("X:\\") # 可以这样获取某目录下的所有文件、目录名
    file_li = ["demo1.csv", "demo2.csv"]
    for file in file_li:
        with open(file, 'r', encoding="utf-8", newline="") as f:
            readfile = csv.reader(f)
            for row in readfile:
                if row[0] == "zhanghao":  # 第一行标题不处理
                    continue
                if row[0] in dic:
                    dic[row[0]] += eval(row[1])
                else:
                    dic[row[0]] = eval(row[1])
    writeStr = "zhanghao,chengji\n"
    for i, j in dic.items():
        writeStr += i + "," + str(j) + "\n"
    with open("result.csv", 'w', encoding="utf-8", newline="") as f:
        f.write(writeStr)  # 数据存入 result.csv
    # !!如果数据量很大的话,建议多次写入,不要都存变量writeStr里,即上4行改为下8行
    # n = 0
    # with open("result.csv", 'w', encoding="utf-8", newline="") as f:
    #     for i, j in dic.items():
    #         writeStr += i + "," + str(j) + "\n"
    #        n += 1
    #         if n % 100 == 0:  # 每100行写入一次
    #             f.write(writeStr)
    #             writeStr = ""
    #     f.write(writeStr)


if __name__ == '__main__':
    main()

csv文件里就是数据分隔符和换行符,用记事本打开就能查看,直接读取也可以,不非要用csv库

基本思路是取两个df索引的交集,把对应数据取出来求和组成新的df,然后两个df把交集的索引删除,这样就有3个不重复索引的df,用concat合并就可以了

import pandas as pd
df1 = pd.read_csv('demo1.csv',index_col='zhanghao')
df2 = pd.read_csv('demo2.csv',index_col='zhanghao')
# print(df1,df2)
all_index = [i for i in df1.index if i in df2.index]
all_chengji = df1.loc[all_index]['chengji']+df2.loc[all_index]['chengji']
df1 = df1.drop(all_index)
df2 = df2.drop(all_index)
df3 = pd.DataFrame({'chengji':all_chengji},columns=['chengji'])
df_all = pd.concat([df1,df2,df3])
print(df_all)

img

这个问题可以有很多处理方式,其中一些方式会影响结果的排序,所以还需要看进一步是否需要保持给出顺序关系。

大致有这么一些策略(主要就是两种策略)
策略一(顺序稳定的策略):

  1. 依次读取2张表,按行,以[zhanghao,chengji]格式加入到一个结果列表(比如RTList)中
  2. 如果新读取的行的zhanghao部分与RTList某个元素值的帐号部分相同,则把新行的chengji部分加到RTList对应元素的changji部分进行更新,不存在相同的,则直接在RTList中添加一个前面格式的元素
  3. 最后遍历RTList进行输出
    这样的可以保证顺序的稳定性,不重复的元素顺序符合 原来 2个文件的顺序,即先 文件一中顺序,再文件二中非重复项的顺序。不过这样处理效率比较低,特别是数据量比较大时,因为需要在每次读取后都遍历RTList来查询是否重复。
import csv
def FindIDX(aList,key):
  rt=-1
  for i in range(len(aList):
    if aList[i][0]==key:
      return i
  return rt
with open("1.csv","r",newline="", encoding='utf-8') as fileObj:
  li1 = list(csv.reader(fileObj))[1:]
print(*li1,sep='\n')
print()
with open("2.csv","r",newline="", encoding='utf-8') as fileObj:
  li2 = list(csv.reader(fileObj))[1:]
print(*li2,sep='\n')
print()
RTList=[]
for v in li1:
  i = FindIDX(RTList, v[0])
    if i>-1:
      RTList[i][1]+=float(v[1])
    else:
      RTList.append([v[0],float(v[1]])
for v in li2:
  i = FindIDX(RTList, v[0])
    if i>-1:
      RTList[i][1]+=float(v[1])
    else:
      RTList.append([v[0],float(v[1]])
writeStr = "zhanghao,chengji\n"
for i in range(len(RTList)):
  writeStr += RTList[i][0]+ "," + str(RTList[i][1]) + "\n"
with open("result.csv", 'w', encoding="utf-8", newline="") as f:
  f.write(writeStr) 

策略二(顺序不稳定策略):
利用字典结构或者其它类似方式,直接形成zhanghaochengji对应关系的k-v,新行读取数据时可以直接查询k是否存在,如果存在就更新,不存在就添加新的k-v对,类似的还有利用set结构一次行的产生所有的k的序列,再根据k遍历输入表(注意是2个),查找对应的v,即chengji求和来和配对构建 输出序列。这样的方式因为python中字典结构组织特性、set组织特性都可能造成输出结果的顺序和原来输入的顺序发生大的变化。 上面 天际的海浪 今夕何夕2112 就是这样的策略。

类似的 比如 溪风沐雪 利用pandas处理 2个输入交集(集合1)、再在2个输入中分别去掉交集涉及元素(形成2个没有重复元素的集合),最后3者
并集作为输出其实也是这种策略的变形,也是顺序不稳定的。 而且这样做需要原来各个输入集自身中都不存在重复k情况。

总的来是策略二效率可能会稍微高一些,但带来顺序不稳定。需要你根据情况选择。

用字典统计一下
你题目的解答代码如下:

import csv

with open("1.csv","r",newline="", encoding='utf-8') as fileObj:
    li1 = list(csv.reader(fileObj))[1:]
print(*li1,sep='\n')
print()
with open("2.csv","r",newline="", encoding='utf-8') as fileObj:
    li2 = list(csv.reader(fileObj))[1:]
print(*li2,sep='\n')
print()
dic = {}
for v in li1:
    dic[v[0]] = v
for v in li2:
    if v[0] in dic:
        dic[v[0]][1] = float(dic[v[0]][1]) + float(v[1])
    else:
        p = v.copy()
        dic[v[0]] = p
        li1.append(p)

print(*li1,sep='\n')

如有帮助,请点击我的回答下方的【采纳该答案】按钮帮忙采纳下,谢谢!

img

pd.concat([df1, df2], axis=0)