简体   繁体   English

如何在 Python 的 CSV 文件中 append 一个新值?

[英]How to append a new value in a CSV file in Python?

I have a CSV sheet, having data like this:我有一张 CSV 表,数据如下:

| not used | Day 1 | Day 2 |
| Person 1    | Score | Score |
| Person 2    | Score | Score |

But with a lot more rows and columns.但是有更多的行和列。 Every day I get progress of how much each person progressed, and I get that data as a dictionary where keys are names and values are score amounts.每天我都会了解每个人的进步程度,并将这些数据作为字典获取,其中键是名称,值是分数。

The thing is, sometimes that dictionary will include new people and not include already existing ones.问题是,有时该词典将包括新人,而不包括已经存在的人。 Then, if a new person comes, it will add 0 as every previous day and if the dict doesn't include already existing person, it will give him 0 score to that day然后,如果一个新人来了,它会像前一天一样加0,如果字典不包括已经存在的人,它会给他当天的0分

My idea of solving this is doing lines = file.readlines() on that CSV file, making a new list of people's names with我解决这个问题的想法是在 CSV 文件上执行 lines = file.readlines() ,使用

for line in lines:
   names.append(line.split(",")[0])

then making a copy of lines (newLines = lines) and going through dict's keys, seeing if that person is already in the csv, if so, append the value followed by a comma But I'm stuck at the part of adding score of 0 Any help or contributions would be appreciated然后制作行的副本(newLines = lines)并通过dict的键,查看该人是否已经在csv中,如果是,append该值后跟逗号但我卡在添加分数0的部分任何帮助或贡献将不胜感激

EXAMPLE: Before I will have this示例:在我拥有这个之前

-,day1,day2,day3
Mark,1500,0,1660
John,1800,1640,0
Peter,1670,1680,1630
Hannah,1480,1520,1570

And I have this dictionary to add我有这本词典要添加

{'Mark': 1750, 'Hannah':1640, 'Brian':1780}

The result should be结果应该是

-,day1,day2,day3,day4
Mark,1500,0,1660,1750
John,1800,1640,0,0
Peter,1670,1680,1630,0
Hannah,1480,1520,1570,1640
Brian,0,0,0,1780

See how Brian is in the dict and not in the before csv and he got added with any other day score 0. I figured out that one line.split(',') would give a list of N elements, where N - 2 will be amount of zero scores to add prior to first day of that person看看布赖恩是如何在字典中而不是在之前的 csv 中,他在任何其他日子得分为 0。我发现一个 line.split(',') 会给出 N 个元素的列表,其中 N - 2 将是在该人的第一天之前添加的零分数

This is easy to do in pandas as an outer join.这在pandas作为外连接很容易做到。 Read the CSV into a dataframe and generate a new dataframe from the dictionary.将 CSV 读入 dataframe 并从字典中生成新的 dataframe。 The join is almost what you want except that since not-a-number values are inserted for empty cells, you need to fill the NaN's with zero and reconvert everything to integer.连接几乎是您想要的,除了因为为空单元格插入非数字值,您需要用零填充 NaN 并将所有内容重新转换为 integer。

The one potential problem is that the CSV is sorted.一个潜在的问题是 CSV 已排序。 You don't simply have the new rows appended to the bottom.您不只是将新行附加到底部。

import pandas as pd
import errno
import os

INDEX_COL = "-"

def add_days_score(filename, colname, scores):
    try:
        df = pd.read_csv(filename, index_col=INDEX_COL)
    except OSError as e:
        if e.errno == errno.ENOENT:
            # file doesn't exist, create empty df
            df = pd.DataFrame([], columns=[INDEX_COL])
            df = df.set_index(INDEX_COl)
        else:
            raise
    new_df = pd.DataFrame.from_dict({colname:scores})
    merged = df.join(new_df, how="outer").fillna(0).astype(int)
    try:
        merged.to_csv(filename + ".tmp", index_label=[INDEX_COL])
    except:
        raise
    else:
        os.rename(filename + ".tmp", filename)
    return merged

#============================================================================
# TEST
#============================================================================

test_file = "this_is_a_test.csv"
before = """-,day1,day2,day3
Mark,1500,0,1660
John,1800,1640,0
Peter,1670,1680,1630
Hannah,1480,1520,1570
"""

after = """-,day1,day2,day3,day4
Brian,0,0,0,1780
Hannah,1480,1520,1570,1640
John,1800,1640,0,0
Mark,1500,0,1660,1750
Peter,1670,1680,1630,0
"""

test_dicts = [
    ["day4", {'Mark': 1750, 'Hannah':1640, 'Brian':1780}],
]

open(test_file, "w").write(before)

for name, scores in test_dicts:
    add_days_score(test_file, name, scores)

print("want\n", after, "\n")
got = open(test_file).read()
print("got\n", got, "\n")
if got != after:
    print("FAILED")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM