【问题标题】:How to filter a large csv file with Python 3如何使用 Python 3 过滤大型 csv 文件
【发布时间】:2021-03-15 19:12:17
【问题描述】:

我有 this csv 文件,但我只需要使用 Python 3 过滤我需要的数据。

简而言之,该 csv 代表了许多聚合的 covid19 数据。但我只需要其中的一部分。我需要所有时间段,只需要意大利、瑞典、德国和法国每百万人中的新死亡人数,仅此而已。

然后,我想根据这个证明创建另一个 CSV:

日期,意大利,瑞典,德国,法国

(例如,01-Apr-2020,13.35,4.52,1.22,6.74)

我的代码如下:

    cases_by_day = dict()
location = {'Italy': 0.0, 'Sweden': 0.0, 'France': 0.0, 'Germany': 0.0}

with open("data.csv") as f:
    v = f.readlines()
    for line in v:
        elements = line.split(",")
        # print(elements)
        date = datetime.strptime(elements[3], "%Y-%m-%d")
        cases_by_day[str(elements[3])] = location

with open("data.csv") as h:
    for line in h:
        a = line.split(",")
        if "Italy" in a[2]:
            u = str(a[3])
            if len(a[15]) == 0:
                cases_by_day[u]["Italy"] = 0.0
            else:
                # print(float(a[15]))
                # print(u)
                cases_by_day[u]["Italy"] = float(a[15])
            # print(cases_by_day[u]["Italy"])
        elif "Sweden" in a[2]:
            i = str(a[3])
            if len(a[15]) == 0:
                cases_by_day[i]["Sweden"] = 0.0
            else:
                cases_by_day[i]["Sweden"] = float(a[15])
        elif "France" in a[2]:
            o = str(a[3])
            if len(a[15]) == 0:
                cases_by_day[o]["France"] = 0.0
            else:
                cases_by_day[o]["France"] = float(a[15])
        elif "Germany" in a[2]:
            p = str(a[3])
            if len(a[15]) == 0:
                cases_by_day[p]["Germany"] = 0.0
            else:
                cases_by_day.get(p)["Germany"] = float(a[15])

print(cases_by_day)

但是,在流程结束时,每个日期键都有相同的嵌套 dict 关联,我不知道为什么

编辑:data.csv 的说明如下:

iso_code, 大陆, 地点, 日期, 总病例数, 新案例, new_cases_smoothed, 总死亡人数, 新的死亡, new_deaths_smoothed, total_cases_per_million, new_cases_per_million, new_cases_smoothed_per_million, total_deaths_per_million, new_deaths_per_million, new_deaths_smoothed_per_million, 16 再生率, ICU_患者, icu_patients_per_million, 医院病人, hosp_patients_per_million, 每周_icu_admissions, 每周_icu_admissions_per_million, 每周医院招生, 每周医院入学人数每百万, 总测试, 新测试, total_tests_per_thousand, new_tests_per_thousand, new_tests_smoothed, new_tests_smoothed_per_thousand, 正率, tests_per_case, 测试单元, stringency_index, 人口, 人口密度, 中年的, aged_65_older, 70 岁以上, 人均国内生产总值, 极端贫困, 心血管死亡率, 糖尿病患病率, 女性吸烟者, 男性吸烟者, 洗手设施, 医院床位每千人, 预期寿命, human_development_index

我感兴趣的列是 2,3 和 15(从零开始计数)。 但是我不想要来自其他国家/地区的数据。

【问题讨论】:

    标签: python python-3.x csv filter dataset


    【解决方案1】:

    我使它适用于以下代码编辑(仅重要部分)

    italy = dict()
    sweden= dict()
    germany= dict()
    france = dict()
    cases_by_day = dict()
    
    with open("data.csv") as f:
        v = f.readlines()
        for line in v:
            elements = line.split(",")
            # print(elements)
            date = datetime.strptime(elements[3], "%Y-%m-%d")
            italy[str(elements[3])] = 0.0
            sweden[str(elements[3])] = 0.0
            germany[str(elements[3])] = 0.0
            france[str(elements[3])] = 0.0
    
    with open("data.csv") as h:
        for line in h:
            a = line.split(",")
            if "Italy" in a[2]:
                u = str(a[3])
                if len(a[15]) == 0:
                    italy[u] = float(0.0)
                else:
                    # print(cases_by_day[u]["Italy"])
                    # print(u)
                    italy[u] = float(a[15])
                # print(cases_by_day[u]["Italy"])
            elif "Sweden" in a[2]:
                i = str(a[3])
                if len(a[15]) == 0:
                    sweden[i] = 0.0
                else:
                    sweden[i] = float(a[15])
            elif "France" in a[2]:
                o = str(a[3])
                if len(a[15]) == 0:
                    france[o] = 0.0
                else:
                    france[o] = float(a[15])
            elif "Germany" in a[2]:
                p = str(a[3])
                if len(a[15]) == 0:
                    germany[p] = 0.0
                else:
                    germany[p] = float(a[15])
    

    所以我基本上把我的听写分开了。

    【讨论】:

      【解决方案2】:

      在您的代码中,您只是创建了字典“嵌套”部分的一个副本,然后在所有情况下都指向cases_by_day 字典中的同一个实例。因此,您只有同一事物的多个副本(引用)。这是问题所在:

      cases_by_day[str(elements[3])] = location
      

      我会建议几件事。如果您想保留 data[day][country] 的格式并具有“零”的表示形式,那么每次您即时找到新日期时只需制作一个新的(空)字典。然后你只需要读取一次文件。你已经很接近了。

      根据您想对数据执行的操作,pandas 解决方案可能会有所帮助,如果您想访问字典,请继续使用上面的修复方法,如果遇到困难,请回复评论!

      【讨论】:

        【解决方案3】:

        我会研究模块 pandas

        import pandas as pd
        
        df = pd.read_csv('data.csv')
        cols =[' continent', ' location', ' new_deaths_per_million']
        subset = ['list of countries needed']
        dff = df.loc[df[' location'].isin(subset)]
        dff[cols].to_csv('nameofyourfile.csv)
        
        

        【讨论】:

        • 我已经编辑添加了我的 csv 文件以便更好地指定
        • 更新的答案,您的列标题在前面有一个额外的空格供参考
        • 我检查了更新的答案,但格式不是我想要的:例如 01-Apr-2020,13.35,4.52,1.22,6.74 生成的 csv 的一行是:18592,2020-01- 29,法国,0.0
        • cols = ['日期','位置','new_deaths_per_million']。 cols 是您要查找的从左到右排列的列的列表。我可能浏览顶部的速度有点太快了,我刚刚从 1 中给出了第 2、3、15 列。
        • 列名已经改了,输出总是错的。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-02
        相关资源
        最近更新 更多