正确的方法来反转pandas.DataFrame?

时间:2013-12-07 17:07:59

标签: python pandas reverse

这是我的代码:

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的正确方法是什么?

7 个答案:

答案 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)

<块引用>

反转 Pandas DataFrame 的正确方法是什么?

TL;DR:df[::-1]

这是客观 IMO 反转 DataFrame 的最佳方法,因为它是一步操作,也非常易读(假设熟悉切片符号)。


长版

我发现 ol' 切片技巧 df[::-1](或等效的 df.loc[::-1]1)是最简洁和惯用的方法反转数据帧。这反映了 python 列表反转语法 lst[::-1] 并且其意图很明确。使用 loc 语法,您还可以根据需要对列进行切片,因此更加灵活。

处理索引时需要考虑的几点:

  • “如果我也想反转索引怎么办?”

    • 你已经完成了。 df[::-1] 反转索引和值。
  • “如果我想从结果中删除索引怎么办?”

  • “如果我想保持索引不变怎么办(IOW,只反转数据,而不是索引)?”

    • 这有点不合常规,因为它暗示索引与数据并不真正相关。也许考虑完全删除它?尽管从技术上讲,可以使用 df[:] = df[::-1] 创建对 df 的就地更新或返回副本的 df.loc[::-1].set_index(df.index) 来实现您的要求。

1:df.loc[::-1]df.iloc[::-1] 是等效的,因为切片语法保持不变,无论您是按位置 (iloc) 或标签 ({{1} }).


证据就在布丁里

enter image description here

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]