【问题标题】:Concat dataframes: give unique names to columns and drop duplicatesConcat 数据框:为列提供唯一名称并删除重复项
【发布时间】:2020-02-19 22:18:05
【问题描述】:

我正在遍历每月的气象站数据。我可以按如下方式连接文件:

path = r"D:\NOAA\output\TEST" 
all_files = glob.glob(path + "/*.csv")

for filename in all_files:
    print filename # prints D:\NOAA\output\TEST\189501.tave.conus.csv
    df = (pd.read_csv(f) for f in all_files)
    concatenated_df = pd.concat(df, axis=1, join='inner')

这会产生以下数据框:

     lat      lon     temp    lat      lon     temp    lat      lon    temp
0  24.5625 -81.8125  21.06  24.5625 -81.8125  17.08  24.5625 -81.8125  22.42
1  24.5625 -81.7708  21.06  24.5625 -81.7708  17.08  24.5625 -81.7708  22.47
2  24.5625 -81.7292  21.06  24.5625 -81.7292  17.08  24.5625 -81.7292  22.47
3  24.5625 -81.6875  21.05  24.5625 -81.6875  17.04  24.5625 -81.6875  22.47
4  24.6042 -81.6458  21.06  24.6042 -81.6458  17.08  24.6042 -81.6458  22.45

latlon 列是相同的,所以我想删除那些重复的列。 temp 列对于每个月度 CSV 文件都是唯一的。我想保留所有这些,但也要给它们有意义的列名,取自文件名,即:

        lat      lon   temp185901   temp185902   temp185903
0    24.5625  -81.8125   21.06        17.08        22.42
1    24.5625  -81.7708   21.06        17.08        22.47
2    24.5625  -81.7292   21.06        17.08        22.47
3    24.5625  -81.6875   21.05        17.04        22.47
4    24.6042  -81.6458   21.06        17.08        22.45

我是 Pandas 的新手(看起来很棒,但要吸收很多东西),我将不胜感激。我认为解决方案在我用于.concat().duplicate().loc() 的参数中。

示例数据:ftp://ftp.commissions.leg.state.mn.us/pub/gis/Temp/NOAA/

【问题讨论】:

  • 一旦你有连接的数据框,你可以用df.drop_duplicates去重复数据
  • df = pd.concat([pd.read_csv(f) for f in all_files])。如果数据文件是公开的,请分享数据文件的链接。
  • 如果您要使用更多内置的 pandas 功能,例如 sum()、avg() 等,我建议不要连接数据帧,而是附加。link
  • @TrentonMcKinney 我添加了示例数据的链接。如您所见,每个 csv 有大约 500,000 行数据...最终我需要计算每个纬度/经度站点的数据跨度>

标签: python pandas duplicates noaa


【解决方案1】:

您可以合并两列并为其他列设置后缀:

temp = df1.merge(df2, on=['lat','lon'], suffixes=('185901','185902'))

       lat      lon  temp185901  temp185902
0  24.5625 -81.8125       21.06       17.08
1  24.5625 -81.7708       21.06       17.08
2  24.5625 -81.7292       21.06       17.08
3  24.5625 -81.6875       21.05       17.04
4  24.6042 -81.6458       21.06       17.08

或者循环

temp.merge(df3, on=['lat','lon']).rename(columns={'temp':'temp185903'})

       lat      lon  temp185901  temp185902  temp185903
0  24.5625 -81.8125       21.06       17.08       22.42
1  24.5625 -81.7708       21.06       17.08       22.47
2  24.5625 -81.7292       21.06       17.08       22.47
3  24.5625 -81.6875       21.05       17.04       22.47
4  24.6042 -81.6458       21.06       17.08       22.45

df = []
for filename in all_files:
    df1 = pd.read_csv(filename)
    # if the first loop
    if not list(df):
       df = df1
    else:
       df = df.merge(df1, on=['lat','lon'])
    df.rename(columns={'temp':'temp'+put_numer_from_filename}, inplace=True)

【讨论】:

  • 我试图在我发布的代码的上下文中使用你的逻辑,所以:df = pd.read_csv(filename, index_col=None, header=0) 和下一行 frame = df.merge(df, on=['lat','lon']) 而不是 concat 方法。这会返回一些看起来像你的东西,但不是......它有纬度,经度,如果我像你一样硬编码它们,它会为列添加后缀,我现在只是关闭该参数,但我只得到 2 个温度列,它们是重复的数据......不是唯一的,所以:第一行是 22.42, 22.42,就像它只取了最后一个数据集(temp185903)并写了两次
  • 你发布的正是我想要的,我只是无法将你所拥有的内容翻译成我发布的内容......
  • @CCantey 我已添加到答案代码中,我如何看待它
  • 所以更新后的代码非常有意义,但我在第一次通过后得到ValueError: The truth value of a DataFrame is ambiguous
  • 它现在似乎可以工作了,但最终的 df 只有初始通道的记录并且临时名称没有改变......所以输出是 lat: 24.5625, lon: -81.8125, temp: 21.06 ...这是第一个数据帧.....所以它就像它没有合并,或者合并没有像我认为的那样工作,即在右侧添加临时列..和名称上的东西,如果我在 shell 中df.rename(columns={'temp':'temp'+filename[20:26]}),它会显示 lat、lon、temp189503,不知道为什么它不在脚本中重命名
【解决方案2】:

这会将新数据作为新行附加到连接的数据框中,并带有“日期”列以指示数据来自哪个文件。修改逻辑以从文件名中获取日期。

import pandas as pd
import glob

path = r'D:\NOAA\output\TEST'
all_files = glob.glob(path + '/*.csv')

df_concat = pd.DataFrame()

for file in all_files:
    df = pd.read_csv(file)
    df['date'] = file #ammend the variable file to get the date from your file names

    df_concat = df_concat.append(df)

【讨论】:

  • 这个问题是纬度/经度对是地图上的点。有 500,000 条纬度/经度记录(点),构成了美国 5 公里的网格。每个点都有 2632 条月度记录(每个 CSV 文件从 1895 年至今)。因此,仅附加会使文件长 13 亿条记录,而且我不知道如何汇总每个点的数据....我想分析每个点的数据 - 1 行数据。跨度>
  • 其实很简单,只需要df.groupby(['lat', 'lon'])。
猜你喜欢
  • 2012-07-18
  • 1970-01-01
  • 2013-05-09
  • 1970-01-01
  • 2011-06-04
  • 1970-01-01
相关资源
最近更新 更多