这是我的代码:
import pandas as pd
data = pd.DataFrame({'Odd':[1,3,5,6,7,9], 'Even':[0,2,4,6,8,10]})
for i in reversed(data):
print(data['Odd'], data['Even'])
当我运行此代码时,我收到以下错误:
Traceback (most recent call last):
File "C:\Python33\lib\site-packages\pandas\core\generic.py", line 665, in _get_item_cache
return cache[item]
KeyError: 5
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\*****\Documents\******\********\****.py", line 5, in <module>
for i in reversed(data):
File "C:\Python33\lib\site-packages\pandas\core\frame.py", line 2003, in __getitem__
return self._get_item_cache(key)
File "C:\Python33\lib\site-packages\pandas\core\generic.py", line 667, in _get_item_cache
values = self._data.get(item)
File "C:\Python33\lib\site-packages\pandas\core\internals.py", line 1656, in get
_, block = self._find_block(item)
File "C:\Python33\lib\site-packages\pandas\core\internals.py", line 1936, in _find_block
self._check_have(item)
File "C:\Python33\lib\site-packages\pandas\core\internals.py", line 1943, in _check_have
raise KeyError('no item named %s' % com.pprint_thing(item))
KeyError: 'no item named 5'
为什么我收到此错误?
我该如何解决?
反转pandas.DataFrame
的正确方法是什么?
答案 0 :(得分:161)
data.reindex(index=data.index[::-1])
或简单地说:
data.iloc[::-1]
会反转您的数据框,如果您希望有一个for
循环从下到上,您可能会这样做:
for idx in reversed(data.index):
print(idx, data.loc[idx, 'Even'], data.loc[idx, 'Odd'])
或
for idx in reversed(data.index):
print(idx, data.Even[idx], data.Odd[idx])
您收到错误是因为reversed
首先调用data.__len__()
,然后返回6.然后它会尝试在data[j - 1]
中为j
调用range(6, 0, -1)
,然后第一次通话将是data[5]
;但在pandas中,数据帧data[5]
表示第5列,并且没有第5列,因此它将引发异常。 (见docs)
答案 1 :(得分:46)
您可以以更简单的方式反转行:
df[::-1]
答案 2 :(得分:9)
现有答案中没有一个在反转数据帧后会重置索引。
为此,请执行以下操作:
data[::-1].reset_index()
这是一个实用程序功能,该功能还根据@Tim的注释删除了旧的索引列:
def reset_my_index(df):
res = df[::-1].reset_index(drop=True)
return(res)
只需将数据框传递到函数中
答案 3 :(得分:7)
df[::-1]
这是客观 IMO 反转 DataFrame 的最佳方法,因为它是一步操作,也非常易读(假设熟悉切片符号)。
我发现 ol' 切片技巧 df[::-1]
(或等效的 df.loc[::-1]
1)是最简洁和惯用的方法反转数据帧。这反映了 python 列表反转语法 lst[::-1]
并且其意图很明确。使用 loc
语法,您还可以根据需要对列进行切片,因此更加灵活。
处理索引时需要考虑的几点:
“如果我也想反转索引怎么办?”
df[::-1]
反转索引和值。“如果我想从结果中删除索引怎么办?”
.reset_index(drop=True)
。“如果我想保持索引不变怎么办(IOW,只反转数据,而不是索引)?”
df[:] = df[::-1]
创建对 df
的就地更新或返回副本的 df.loc[::-1].set_index(df.index)
来实现您的要求。 1:df.loc[::-1]
和 df.iloc[::-1]
是等效的,因为切片语法保持不变,无论您是按位置 (iloc
) 或标签 ({{1} }).
X 轴代表数据集大小。 Y 轴表示反转所需的时间。没有任何方法可以扩展以及切片技巧,它一直在图的底部。 Benchmarking code 供参考,使用 perfplot 生成的图。
loc
显然是一个流行的解决方案,但乍一看,对于不熟悉的读者来说,这段代码“反转数据帧”有多明显?此外,这是反转索引,然后使用该中间结果到 df.reindex(index=df.index[::-1])
,所以这本质上是一个TWO 步操作(当它可能只是一个时)。
reindex
在大多数情况下可能适用,因为您有一个简单的范围索引,但这假设您的索引是按升序排序的,因此不能很好地概括。
请不要使用df.sort_index(ascending=False)
。我看到一些建议反向迭代的选项。无论您的用例是什么,都可能有可用的矢量化方法,但如果没有,那么您可以使用更合理的方法,例如列表推导式。有关为何 iterrows
是反模式的更多详细信息,请参阅 How to iterate over rows in a DataFrame in Pandas。
答案 4 :(得分:4)
正确的方法是:
data = data.sort_index(ascending=False)
此方法的优点是(1)是一行,(2)不需要实用程序功能,最重要的是(3)实际上没有更改数据框中的任何数据。
答案 5 :(得分:3)
这有效:
for i,r in data[::-1].iterrows():
print(r['Odd'], r['Even'])
答案 6 :(得分:2)
最简单的解决方案可能是
data = data[::-1]