【问题标题】:How to modify DataFrames so that they only have rows with shared index values in Pandas?如何修改 DataFrame 以使它们在 Pandas 中只有具有共享索引值的行?
【发布时间】:2020-07-06 18:19:07
【问题描述】:

所以,我是一名数据科学专业的学生,​​在 Python Pandas 中处理一些数据,并且我有两个索引为日期的数据帧(每个数据帧都是通过使用 pandas.readcsv("filepath", index_col="DATE" 读取 CSV 文件生成的) , parse_dates=True, dayfirst=True))。我想要做的是修改这些数据帧,使它们每个只包含索引值由它们共享的行 - 这样,我可以直接比较它们以查找数据中的相关性。

在过去的几个小时里,我一直在搜索文档和 SO 寻找方法,目前,我得到了以下代码:

common_dates = list(set(df1.index.values).intersection(df2.index.values))
print(common_dates)
print(normalized_house_index_data.index.values)
df1= df1.take(common_dates)
df2= df2.take(common_dates)

但是,这给了我一个索引越界错误,即使 common_dates 应该从 index.values 数组中的项目构造。当我查看作为故障排除的一部分添加的 print() 语句的输出时,我看到以下 common_dates:

[numpy.datetime64('2000-12-31T00:00:00.000000000'), numpy.datetime64('2001-12-31T00:00:00.000000000'), numpy.datetime64('2004-12-31T00:00:00.000000000'), numpy.datetime64('2003-12-31T00:00:00.000000000'), #and more values

df1.index.values 如下:

['2000-12-31T00:00:00.000000000' '2001-12-31T00:00:00.000000000'
 '2002-12-31T00:00:00.000000000' '2003-12-31T00:00:00.000000000' #and more values

df2.index.values 的值看起来类似于 df1。

['1947-12-31T00:00:00.000000000' '1948-12-31T00:00:00.000000000'
#lots of values
 '1997-12-31T00:00:00.000000000' '1998-12-31T00:00:00.000000000'
 '1999-12-31T00:00:00.000000000' '2000-12-31T00:00:00.000000000'
 '2001-12-31T00:00:00.000000000' '2002-12-31T00:00:00.000000000'
#more values

这会产生“索引超出范围”错误。我尝试使用 list(map(str, common_dates) 将 common_dates 转换为字符串,因为看起来可能存在某种类型的不匹配,但这给出了一个“invalid literal for int() with base 10: '2000- 12-31T00:00:00.000000000'" 错误;我尝试将它们类似地转换为 int 或 numpy.datetime64,但这些都给出了“索引超出范围”错误。

我还尝试了另一种使用 df1.iterrows() 的方法:

droplist = []
for date, value in df1.iterrows():
    if date not in common_dates:
        droplist.append(date)
df1= df1.drop(droplist)

我还尝试了一个版本,将每一行的日期直接与 df2.index.values 的值进行比较。这两种方法都会导致从表中删除所有行,而不是仅删除不匹配的行。

我做错了什么,在这里?我只是采取了错误的方法,还是我遗漏了什么?

【问题讨论】:

  • 我认为你需要df = pd.merge(df1, df2, left_index=True, right_index=True) 然后print (df.index) 是常见的日期。
  • 我不想合并数据框;我想将它们分开,以便以后可以更轻松地进行比较。
  • 嗯,所以问题是缺少minimal, complete, and verifiable example
  • @jezrael 怎么样?我已经给出了创建数据帧、操作它们的代码以及调试输出的方法。你还想要什么?
  • 我无法运行代码来验证index out of bounds error,如果正确,我该如何测试您的解决方案?

标签: python pandas dataframe


【解决方案1】:

我认为 take 有问题,我工作 DataFrame.loc 以通过常用索引进行选择:

a = pd.DatetimeIndex(['2000-12-31T00:00:00.000000000',
                      '2001-12-31T00:00:00.000000000',
                      '2002-12-31T00:00:00.000000000', 
                      '2003-12-31T00:00:00.000000000'])

b = pd.DatetimeIndex(['1947-12-31T00:00:00.000000000',
                      '1948-12-31T00:00:00.000000000',
                      '1997-12-31T00:00:00.000000000',
                      '1998-12-31T00:00:00.000000000',
                      '1999-12-31T00:00:00.000000000',
                      '2000-12-31T00:00:00.000000000',
                      '2001-12-31T00:00:00.000000000',
                      '2002-12-31T00:00:00.000000000'])

df1 = pd.DataFrame(index=a)
df2 = pd.DataFrame(index=b)

common_dates = list(set(df1.index.values).intersection(df2.index.values))
print(common_dates)
[numpy.datetime64('2000-12-31T00:00:00.000000000'), 
 numpy.datetime64('2001-12-31T00:00:00.000000000'), 
 numpy.datetime64('2002-12-31T00:00:00.000000000')]

也可以将Index.intersection 用于公共索引:

common_dates = df1.index.intersection(df2.index)
print(common_dates)
DatetimeIndex(['2000-12-31', '2001-12-31', '2002-12-31'], 
              dtype='datetime64[ns]', freq='A-DEC')

df1= df1.loc[common_dates]
df2= df2.loc[common_dates]
print (df1)
Empty DataFrame
Columns: []
Index: [2000-12-31 00:00:00, 2001-12-31 00:00:00, 2002-12-31 00:00:00]

print (df2)
Empty DataFrame
Columns: []
Index: [2000-12-31 00:00:00, 2001-12-31 00:00:00, 2002-12-31 00:00:00]

【讨论】:

  • @nick012000 - 感谢您的耐心等待!快乐编码 ;)
猜你喜欢
  • 1970-01-01
  • 2021-04-20
  • 2018-01-18
  • 2020-12-24
  • 1970-01-01
  • 2017-03-11
  • 2022-08-09
  • 2011-09-08
  • 2016-02-19
相关资源
最近更新 更多