Python Pandas 在索引上加入数据框

Posted

技术标签:

【中文标题】Python Pandas 在索引上加入数据框【英文标题】:Python Pandas join dataframes on index 【发布时间】:2014-07-10 07:47:55 【问题描述】:

我正在尝试加入同一列“日期”的数据框,代码如下:

import pandas as pd
from datetime import datetime
df_train_csv = pd.read_csv('./train.csv',parse_dates=['Date'],index_col='Date')

start = datetime(2010, 2, 5)
end = datetime(2012, 10, 26)

df_train_fly = pd.date_range(start, end, freq="W-FRI")
df_train_fly = pd.DataFrame(pd.Series(df_train_fly), columns=['Date'])

merged = df_train_csv.join(df_train_fly.set_index(['Date']), on = ['Date'], how = 'right', lsuffix='_x')

它抱怨数据框 df_train_csv 没有名为“日期”的列。我想将两个数据框中的“日期”设置为索引,我想知道以日期为索引加入数据框的最佳方法是什么?

更新:

那是样本数据

Date,Weekly_Sales
2010-02-05,24924.5
2010-02-12,46039.49
2010-02-19,41595.55
2010-02-26,19403.54
2010-03-05,21827.9
2010-03-12,21043.39
2010-03-19,22136.64
2010-03-26,26229.21
2010-04-02,57258.43
2010-04-09,42960.91
2010-04-16,17596.96
2010-04-23,16145.35
2010-04-30,16555.11
2010-05-07,17413.94
2010-05-14,18926.74
2010-05-21,14773.04
2010-05-28,15580.43
2010-06-04,17558.09
2010-06-11,16637.62
2010-06-18,16216.27
2010-06-25,16328.72
2010-07-02,16333.14
2010-07-09,17688.76
2010-07-16,17150.84
2010-07-23,15360.45
2010-07-30,15381.82
2010-08-06,17508.41
2010-08-13,15536.4
2010-08-20,15740.13
2010-08-27,15793.87
2010-09-03,16241.78
2010-09-10,18194.74
2010-09-17,19354.23
2010-09-24,18122.52
2010-10-01,20094.19
2010-10-08,23388.03
2010-10-15,26978.34
2010-10-22,25543.04
2010-10-29,38640.93
2010-11-05,34238.88
2010-11-12,19549.39
2010-11-19,19552.84
2010-11-26,18820.29
2010-12-03,22517.56
2010-12-10,31497.65
2010-12-17,44912.86
2010-12-24,55931.23
2010-12-31,19124.58
2011-01-07,15984.24
2011-01-14,17359.7
2011-01-21,17341.47
2011-01-28,18461.18
2011-02-04,21665.76
2011-02-11,37887.17
2011-02-18,46845.87
2011-02-25,19363.83
2011-03-04,20327.61
2011-03-11,21280.4
2011-03-18,20334.23
2011-03-25,20881.1
2011-04-01,20398.09
2011-04-08,23873.79
2011-04-15,28762.37
2011-04-22,50510.31
2011-04-29,41512.39
2011-05-06,20138.19
2011-05-13,17235.15
2011-05-20,15136.78
2011-05-27,15741.6
2011-06-03,16434.15
2011-06-10,15883.52
2011-06-17,14978.09
2011-06-24,15682.81
2011-07-01,15363.5
2011-07-08,16148.87
2011-07-15,15654.85
2011-07-22,15766.6
2011-07-29,15922.41
2011-08-05,15295.55
2011-08-12,14539.79
2011-08-19,14689.24
2011-08-26,14537.37
2011-09-02,15277.27
2011-09-09,17746.68
2011-09-16,18535.48
2011-09-23,17859.3
2011-09-30,18337.68
2011-10-07,20797.58
2011-10-14,23077.55
2011-10-21,23351.8
2011-10-28,31579.9
2011-11-04,39886.06
2011-11-11,18689.54
2011-11-18,19050.66
2011-11-25,20911.25
2011-12-02,25293.49
2011-12-09,33305.92
2011-12-16,45773.03
2011-12-23,46788.75
2011-12-30,23350.88
2012-01-06,16567.69
2012-01-13,16894.4
2012-01-20,18365.1
2012-01-27,18378.16
2012-02-03,23510.49
2012-02-10,36988.49
2012-02-17,54060.1
2012-02-24,20124.22
2012-03-02,20113.03
2012-03-09,21140.07
2012-03-16,22366.88
2012-03-23,22107.7
2012-03-30,28952.86
2012-04-06,57592.12
2012-04-13,34684.21
2012-04-20,16976.19
2012-04-27,16347.6
2012-05-04,17147.44
2012-05-11,18164.2
2012-05-18,18517.79
2012-05-25,16963.55
2012-06-01,16065.49
2012-06-08,17666
2012-06-15,17558.82
2012-06-22,16633.41
2012-06-29,15722.82
2012-07-06,17823.37
2012-07-13,16566.18
2012-07-20,16348.06
2012-07-27,15731.18
2012-08-03,16628.31
2012-08-10,16119.92
2012-08-17,17330.7
2012-08-24,16286.4
2012-08-31,16680.24
2012-09-07,18322.37
2012-09-14,19616.22
2012-09-21,19251.5
2012-09-28,18947.81
2012-10-05,21904.47
2012-10-12,22764.01
2012-10-19,24185.27
2012-10-26,27390.81

我将从 csv 文件中读取它。但有时,可能会缺少几个星期。因此,我正在尝试生成这样的日期范围:

df_train_fly = pd.date_range(start, end, freq="W-FRI")

这个生成的数据框包含该范围内的所有星期,因此我需要将这两个数据框合并为一个。

如果我从 iPython 控制台检查 df_train_csv['Date'] 和 df_train_fly['Date'],它们都显示为 dtype: datetime64[ns]

【问题讨论】:

好吧,它不起作用,因为您在读取 ​​csv 时将index_col 设置为日期,您可以不将 index_col 设置为“Date”,也可以将 df_train_fly 中的“Date”col 设置为索引列也将left_index=True, right_index=True 传递给连接 实际上你不能传递 left_index=True 等等。除非你做一个merge 所以如果你想使用 join 然后把index_col='Date' 参数放到read_csv 我认为在您的情况下,如果您这样做,它应该可以工作:merged = df_train_csv.join(df_train_fly, how = 'right', lsuffix='_x') 所以删除on=['Date'] 参数,因为这是用于指定要加入的列,如果您忽略它,默认值为None 将使用索引加入 我认为它应该可以工作,你使用的是什么版本的 pandas、numpy 和 python。您还可以发布完整的数据吗? 我使用了您提到的另一个选项:不设置'on'参数并让它们自动加入索引,这是有效的!顺便说一句,要设置数据帧的索引,像这样 df_train_fly.set_index('Date') 并没有真正改变索引,我必须将值分配回 df: df_train_fly = df_train_fly.set_index('Date') 使它工作。 【参考方案1】:

让我们来剖析一下:

df_train_csv = pd.read_csv('./train.csv',parse_dates=['Date'],index_col='Date')

好的,这里的第一个问题是您已指定索引列应为“日期”,这意味着您将不再有“日期”列。

start = datetime(2010, 2, 5)
end = datetime(2012, 10, 26)

df_train_fly = pd.date_range(start, end, freq="W-FRI")
df_train_fly = pd.DataFrame(pd.Series(df_train_fly), columns=['Date'])

merged = df_train_csv.join(df_train_fly.set_index(['Date']), on = ['Date'], how = 'right', lsuffix='_x')

所以上面的连接将不会像报告的错误一样起作用,所以为了解决这个问题:

# remove the index_col param
df_train_csv = pd.read_csv('./train.csv',parse_dates=['Date'])
# don't set the index on df_train_fly
merged = df_train_csv.join(df_train_fly, on = ['Date'], how = 'right', lsuffix='_x')

或者不要设置“on”参数:

merged = df_train_csv.join(df_train_fly, how = 'right', lsuffix='_x')

上面将使用两个df的索引加入

您也可以通过执行合并来获得相同的结果:

merged = df_train_csv.merge(df_train_fly.set_index(['Date']), left_index=True, right_index=True, how = 'right', lsuffix='_x')

【讨论】:

您好 EdCum,感谢您的帮助!我删除了 index_col='Date' 并使用了 merge = df_train_fly.join(df_train_csv, on = ['Date'], how = 'left', lsuffix='_x')。但它给了我非常奇怪的结果(所有列都是 NaN,df_train_csv 中的日期是 NaT),我猜 df_train_csv 中的日期与 df_train_fly 中的日期格式不同,因为当我使用内部连接时,将返回一个空集。时间戳有什么问题? @wuha 你能用相同的数据编辑你的问题并输出“日期”列值吗

以上是关于Python Pandas 在索引上加入数据框的主要内容,如果未能解决你的问题,请参考以下文章

Python Pandas - 如何在具有不同级别数的索引上加入 DataFrames?

Python Pandas 索引错误:列表索引超出范围

为 pandas 数据框 Python 设置索引

python pandas数据框联合合并列表到索引

Python Pandas 加入索引值

Python pandas数据框“日期”索引xlsx和csv中的不同格式