Concat DataFrame 重新索引仅对唯一值的 Index 对象有效
- 2025-03-19 08:56:00
- admin 原创
- 50
问题描述:
我正在尝试连接以下数据框:
df1
price side timestamp
timestamp
2016-01-04 00:01:15.631331072 0.7286 2 1451865675631331
2016-01-04 00:01:15.631399936 0.7286 2 1451865675631400
2016-01-04 00:01:15.631860992 0.7286 2 1451865675631861
2016-01-04 00:01:15.631866112 0.7286 2 1451865675631866
和:
df2
bid bid_size offer offer_size
timestamp
2016-01-04 00:00:31.331441920 0.7284 4000000 0.7285 1000000
2016-01-04 00:00:53.631324928 0.7284 4000000 0.7290 4000000
2016-01-04 00:01:03.131234048 0.7284 5000000 0.7286 4000000
2016-01-04 00:01:12.131444992 0.7285 1000000 0.7286 4000000
2016-01-04 00:01:15.631364096 0.7285 4000000 0.7290 4000000
和
data = pd.concat([df1,df2], axis=1)
但我得到以下输出:
InvalidIndexError Traceback (most recent call last)
<ipython-input-38-2e88458f01d7> in <module>()
----> 1 data = pd.concat([df1,df2], axis=1)
2 data = data.fillna(method='pad')
3 data = data.fillna(method='bfill')
4 data['timestamp'] = data.index.values#converting to datetime
5 data['timestamp'] = pd.to_datetime(data['timestamp'])#converting to datetime
/usr/local/lib/python2.7/site-packages/pandas/tools/merge.pyc in concat(objs, axis, join, join_axes, ignore_index, keys, levels, names, verify_integrity, copy)
810 keys=keys, levels=levels, names=names,
811 verify_integrity=verify_integrity,
--> 812 copy=copy)
813 return op.get_result()
814
/usr/local/lib/python2.7/site-packages/pandas/tools/merge.pyc in __init__(self, objs, axis, join, join_axes, keys, levels, names, ignore_index, verify_integrity, copy)
947 self.copy = copy
948
--> 949 self.new_axes = self._get_new_axes()
950
951 def get_result(self):
/usr/local/lib/python2.7/site-packages/pandas/tools/merge.pyc in _get_new_axes(self)
1013 if i == self.axis:
1014 continue
-> 1015 new_axes[i] = self._get_comb_axis(i)
1016 else:
1017 if len(self.join_axes) != ndim - 1:
/usr/local/lib/python2.7/site-packages/pandas/tools/merge.pyc in _get_comb_axis(self, i)
1039 raise TypeError("Cannot concatenate list of %s" % types)
1040
-> 1041 return _get_combined_index(all_indexes, intersect=self.intersect)
1042
1043 def _get_concat_axis(self):
/usr/local/lib/python2.7/site-packages/pandas/core/index.pyc in _get_combined_index(indexes, intersect)
6120 index = index.intersection(other)
6121 return index
-> 6122 union = _union_indexes(indexes)
6123 return _ensure_index(union)
6124
/usr/local/lib/python2.7/site-packages/pandas/core/index.pyc in _union_indexes(indexes)
6149
6150 if hasattr(result, 'union_many'):
-> 6151 return result.union_many(indexes[1:])
6152 else:
6153 for other in indexes[1:]:
/usr/local/lib/python2.7/site-packages/pandas/tseries/index.pyc in union_many(self, others)
959 else:
960 tz = this.tz
--> 961 this = Index.union(this, other)
962 if isinstance(this, DatetimeIndex):
963 this.tz = tz
/usr/local/lib/python2.7/site-packages/pandas/core/index.pyc in union(self, other)
1553 result.extend([x for x in other._values if x not in value_set])
1554 else:
-> 1555 indexer = self.get_indexer(other)
1556 indexer, = (indexer == -1).nonzero()
1557
/usr/local/lib/python2.7/site-packages/pandas/core/index.pyc in get_indexer(self, target, method, limit, tolerance)
1890
1891 if not self.is_unique:
-> 1892 raise InvalidIndexError('Reindexing only valid with uniquely'
1893 ' valued Index objects')
1894
InvalidIndexError: Reindexing only valid with uniquely valued Index objects
我已经删除了额外的列并删除了可能存在冲突的重复项和 NA - 但我根本不知道出了什么问题。
解决方案 1:
列名重复!
就我而言,问题是由于我有重复的列名。
解决方案 2:
您可以缓解此错误,而无需更改数据或删除重复项。只需使用DataFrame.reset_index创建一个新索引:
df = df.reset_index()
旧索引将作为数据框中的一列保存,但如果您不需要它,您可以执行以下操作:
df = df.reset_index(drop=True)
有些人更喜欢:
df.reset_index(inplace=True, drop=True)
解决方案 3:
pd.concat
要求索引是唯一的。要删除具有重复索引的行,请使用
df = df.loc[~df.index.duplicated(keep='first')]
import pandas as pd
from pandas import Timestamp
df1 = pd.DataFrame(
{'price': [0.7286, 0.7286, 0.7286, 0.7286],
'side': [2, 2, 2, 2],
'timestamp': [1451865675631331, 1451865675631400,
1451865675631861, 1451865675631866]},
index=pd.DatetimeIndex(['2000-1-1', '2000-1-1', '2001-1-1', '2002-1-1']))
df2 = pd.DataFrame(
{'bid': [0.7284, 0.7284, 0.7284, 0.7285, 0.7285],
'bid_size': [4000000, 4000000, 5000000, 1000000, 4000000],
'offer': [0.7285, 0.729, 0.7286, 0.7286, 0.729],
'offer_size': [1000000, 4000000, 4000000, 4000000, 4000000]},
index=pd.DatetimeIndex(['2000-1-1', '2001-1-1', '2002-1-1', '2003-1-1', '2004-1-1']))
df1 = df1.loc[~df1.index.duplicated(keep='first')]
# price side timestamp
# 2000-01-01 0.7286 2 1451865675631331
# 2001-01-01 0.7286 2 1451865675631861
# 2002-01-01 0.7286 2 1451865675631866
df2 = df2.loc[~df2.index.duplicated(keep='first')]
# bid bid_size offer offer_size
# 2000-01-01 0.7284 4000000 0.7285 1000000
# 2001-01-01 0.7284 4000000 0.7290 4000000
# 2002-01-01 0.7284 5000000 0.7286 4000000
# 2003-01-01 0.7285 1000000 0.7286 4000000
# 2004-01-01 0.7285 4000000 0.7290 4000000
result = pd.concat([df1, df2], axis=0)
print(result)
bid bid_size offer offer_size price side timestamp
2000-01-01 NaN NaN NaN NaN 0.7286 2 1.451866e+15
2001-01-01 NaN NaN NaN NaN 0.7286 2 1.451866e+15
2002-01-01 NaN NaN NaN NaN 0.7286 2 1.451866e+15
2000-01-01 0.7284 4000000 0.7285 1000000 NaN NaN NaN
2001-01-01 0.7284 4000000 0.7290 4000000 NaN NaN NaN
2002-01-01 0.7284 5000000 0.7286 4000000 NaN NaN NaN
2003-01-01 0.7285 1000000 0.7286 4000000 NaN NaN NaN
2004-01-01 0.7285 4000000 0.7290 4000000 NaN NaN NaN
注意,还有pd.join
,它可以根据索引连接 DataFrames,并根据how
参数处理非唯一索引。具有重复索引的行不会被删除。
In [94]: df1.join(df2)
Out[94]:
price side timestamp bid bid_size offer \n2000-01-01 0.7286 2 1451865675631331 0.7284 4000000 0.7285
2000-01-01 0.7286 2 1451865675631400 0.7284 4000000 0.7285
2001-01-01 0.7286 2 1451865675631861 0.7284 4000000 0.7290
2002-01-01 0.7286 2 1451865675631866 0.7284 5000000 0.7286
offer_size
2000-01-01 1000000
2000-01-01 1000000
2001-01-01 4000000
2002-01-01 4000000
In [95]: df1.join(df2, how='outer')
Out[95]:
price side timestamp bid bid_size offer offer_size
2000-01-01 0.7286 2 1.451866e+15 0.7284 4000000 0.7285 1000000
2000-01-01 0.7286 2 1.451866e+15 0.7284 4000000 0.7285 1000000
2001-01-01 0.7286 2 1.451866e+15 0.7284 4000000 0.7290 4000000
2002-01-01 0.7286 2 1.451866e+15 0.7284 5000000 0.7286 4000000
2003-01-01 NaN NaN NaN 0.7285 1000000 0.7286 4000000
2004-01-01 NaN NaN NaN 0.7285 4000000 0.7290 4000000
解决方案 4:
当您搜索错误但答案不完整时,此帖子会排在最前面,所以让我添加我的答案。发生此错误还有另一个原因:如果您的数据框中有重复的列,您将无法连接并引发此错误。事实上,即使在原始问题中也有两列称为timestamp
。因此,最好检查len(df.columns) == len(set(df.columns))
您要连接的所有数据框是否。
解决方案 5:
作为尼古拉斯莫利的回答的补充,当你发现这甚至不起作用时:
df = df.reset_index(drop=True)
您应该检查列是否唯一。如果不是,即使重置索引也不起作用。应先删除重复的列才能使其起作用。
解决方案 6:
这是因为您有重复的列。连接之前,删除每个 DataFrame 中的重复列,如下所示:
df = df.loc[:,~df.columns.duplicated()].reset_index(drop=True)
解决方案 7:
当列名有重复时也会发生这种情况。
解决方案 8:
您的两个数据框的索引不匹配。
当 pandas 水平执行 concat 操作(axis=1)时,它会尝试找到具有相同索引的行并水平连接它们。因此,df1 中索引为 1 的行将与索引为 1 的行匹配。因此,如果两个索引都存在问题,则重置其中一个或两个的索引。
pd.concat([df1.reset_index(drop=True), df2], axis=1)
或者
pd.concat([df1.reset_index(drop=True), df2.reset_index(drop=True), axis=1])
解决方案 9:
两个 DF 之间的索引相同
导致此问题的另一个原因可能是df1
和df2
彼此之间可能具有相同的索引。例如,两个 dfs 可能具有相同的索引idx1
。
要检查这是否是问题所在,您可以查看以下输出是否不是空列表:
print([org_name for org_name in cum_df.index if org_name in df_from_2002.index])
我建议的解决方案是重命名索引(因此df1
会继续拥有idx1
并且您会更改为idx1
),并在连接()之后,使用以下代码合并两个索引(如果您需要获取它们的总和):idx2
`df2`df1 = pd.concat([df1, df2])
df1.iloc[idx1] = df1.iloc[[idx1, idx2]].sum()
然后删除idx2
:
df1.drop([idx2], inplace=True)
解决方案 10:
当我尝试连接两个具有重复列名的数据框时发生了这种情况!
假设我想删除第一个重复的列:
duplicated_column = 'column'
df_tmp = df[duplicated_column].T
df_tmp = df_tmp.iloc[1: , :]
df = df.drop([duplicated_column], axis=1)
df = pd.concat([df, df_tmp.T], axis=1)
解决方案 11:
对我来说,问题是重复的列标签,就像这里的许多其他人提到的那样。为了仅保留重复项的第一列,我使用了以下内容:
df=df.T[~df.T.index.duplicated(keep='first')].T
解决方案 12:
这里的答案很有帮助,但在某些情况下,即使存在重复的列,concat 对我来说也很好用。然而,在某些情况下它不起作用并引发了InvalidIndexError
。
事实证明,如果重复列的顺序相同,它可以正常工作,但如果重复列的顺序不同,则会引发错误。
运行良好的示例:
df = pd.DataFrame({'a': [1, 2, 3], 'b': [5, 6, 7], 'c': [9, 10, 11]})
df1 = pd.DataFrame({'a': [12], 'b': [13], 'c': [14]})
df.rename(columns={
'c': 'b'
}, inplace=True)
df1.rename(columns={
'c': 'b'
}, inplace=True)
print(pd.concat([df, df1]))
Output:
a b b
0 1 5 9
1 2 6 10
2 3 7 11
0 12 13 14
不起作用的示例:
df = pd.DataFrame({'b': [1, 2, 3], 'a': [5, 6, 7], 'c': [9, 10, 11]})
df1 = pd.DataFrame({'a': [12], 'b': [13], 'c': [14]})
df.rename(columns={
'c': 'b'
}, inplace=True)
df1.rename(columns={
'c': 'b'
}, inplace=True)
print(pd.concat([df, df1]))
Output:
pandas.errors.InvalidIndexError: Reindexing only valid with uniquely
valued Index objects
解决方案 13:
如果您使用 axis=0 进行连接,则下面的解决方案将起作用,这意味着您要附加行而不是列
原因:你的一个或两个数据框可能有重复的列 df1 列可能是 A, B, C, C df2 列可能是 B, D
在这种情况下,A 有重复的 C 列,因此您可能会收到此错误。删除 df1 中的一列 C 列,希望问题能够得到解决
df1['C'].is_unique
解决方案 14:
我遇到了同样的情况,但后来我注意到我的索引(日期时间)有不同的最后日期。当我使用相同的时间范围间隔为两个数据框固定日期时,pd.concat()
工作正常。
解决方案 15:
df1 = pd.DataFrame.from_dict({'A':[1,2,3], 'B':[110,120,230]})
df2 = pd.DataFrame.from_dict({'B':[11,12,23], 'C':[10,11,12]})
df2.rename(columns={'C':'B'}, inplace=True)
pd.concat([df1,df2])
InvalidIndexError:仅对具有唯一值的 Index 对象进行重新索引才有效
上述代码将在连接数据框的行时复制错误。发生错误的原因是,df2 中有两列具有相同的名称“B”
A B
0 1 110
1 2 120
2 3 230
B B
0 11 10
1 12 11
2 23 12
解决方案 16:
在我的例子中,其中一个 pandas DataFrames 有多个同名的列
解决方案 17:
该页面的最佳解决方案:
https://pandas.pydata.org/pandas-docs/version/0.20/merging.html
df = pd.concat([df1, df2], axis=1, join_axes=[df1.index])
扫码咨询,免费领取项目管理大礼包!