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

Mic*_*ael 91 python reverse pandas

这是我的代码:

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'])
Run Code Online (Sandbox Code Playgroud)

当我运行此代码时,我收到以下错误:

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'
Run Code Online (Sandbox Code Playgroud)

为什么我收到此错误?
我该如何解决这个问题?
逆转的正确方法是pandas.DataFrame什么?

beh*_*uri 185

data.reindex(index=data.index[::-1])
Run Code Online (Sandbox Code Playgroud)

或者干脆:

data.iloc[::-1]
Run Code Online (Sandbox Code Playgroud)

将反转您的数据框,如果您想要一个for从下到上的循环,您可以这样做:

for idx in reversed(data.index):
    print(idx, data.loc[idx, 'Even'], data.loc[idx, 'Odd'])
Run Code Online (Sandbox Code Playgroud)

要么

for idx in reversed(data.index):
    print(idx, data.Even[idx], data.Odd[idx])
Run Code Online (Sandbox Code Playgroud)

因为你得到一个错误reversed首先调用data.__len__()返回6,然后试图调用data[j - 1]用于jrange(6, 0, -1)和第一个电话会data[5]; 但在pandas中,dataframe data[5]表示第5列,并且没有第5列,因此它将引发异常.(见文档)

  • df = df [::-1]`是pythonic的有效解决方案吗? (3认同)
  • @tommy.carstensen 是的,它应该是最佳答案 (3认同)
  • @tommy.carstensen 是的,它比这个解决方案更有效,而且速度更快。请参阅[此处](/sf/answers/4577399431/)的基本原理和基准。 (3认同)
  • 有什么方法可以**就地**?相当于假设的`data.reindex(index=data.index[::-1], inplace=True)` (2认同)
  • 可以先执行data = data.reindex(index = data.index [::-1]),然后执行data.reset_index(inplace = True,drop = True),然后将其重置。 (2认同)

use*_*951 53

您可以以更简单的方式反转行:

df[::-1]
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢用 `pd.Series.reverse = pd.DataFrame.reverse = lambda self: self[::-1]` 定义我自己的 `reverse()` 方法,因为它在链接方法时看起来更好,例如 `df.reverse ().iterrows()`。 (5认同)
  • `df[::-1]` 应该是最好的方法,到目前为止,这优于本页上的其他答案,请参阅[此处](/sf/answers/4577399431/)了解计时。 (2认同)

Cyb*_*tic 18

在反转数据帧后,现有的答案都不会重置索引。

为此,请执行以下操作:

 data[::-1].reset_index()
Run Code Online (Sandbox Code Playgroud)

根据@Tim 的评论,这是一个实用程序函数,它也删除了旧索引列:

def reset_my_index(df):
  res = df[::-1].reset_index(drop=True)
  return(res)
Run Code Online (Sandbox Code Playgroud)

只需将您的数据框传递到函数中

  • 您可能想要 `drop=True`,即:`data[::-1].reset_index(drop=True)`,否则旧索引将作为列添加到 DataFrame 上。 (3认同)
  • @endolith 一些库希望数据帧被索引。例如,一些时间序列预测库期望索引框架作为输入,以便它可以对时间序列进行建模,同时保持时间步长(日、月、年等)的不可知性。因此,您可能正在使用数据框,对其进行转换,这会弄乱索引。因此重新索引框架是很常见的。 (2认同)

cs9*_*s95 15

反转熊猫数据帧的正确方法是什么?

特尔;博士: df[::-1]

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


长版

我发现 ol' 切片技巧df[::-1](或等效的1)是反转 DataFrame 的最简洁和惯用的方法。这反映了 python 列表反转语法,其意图很明确。使用语法,您还可以根据需要对列进行切片,因此它更灵活一些。df.loc[::-1]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) 或标签 ( loc)反转。


证据就在布丁里

在此处输入图片说明

X 轴表示数据集大小。Y 轴表示反转所需的时间。没有任何方法可以扩展以及切片技巧,它一直在图的底部。基准代码供参考,使用perfplot生成的


对其他解决方案的评论

  • df.reindex(index=df.index[::-1])显然是一个流行的解决方案,但乍一看,对于不熟悉的读者来说,这段代码“反转数据帧”有多明显?此外,这是反转索引,然后使用该中间结果到reindex,所以这本质上是两个步操作(当它可能已经只是一个)。

  • df.sort_index(ascending=False) 在大多数情况下,如果您有一个简单的范围索引,可能会工作,但这假设您的索引是按升序排序的,因此不能很好地概括。

  • 请不要使用iterrows。我看到一些建议反向迭代的选项。无论您的用例是什么,都可能有可用的矢量化方法,但如果没有,那么您可以使用更合理的方法,例如列表推导式。有关为什么是反模式的更多详细信息,请参阅如何在 Pandas 中迭代 DataFrame 中的行iterrows


小智 5

如果处理排序范围索引,一种方法是:

data = data.sort_index(ascending=False)
Run Code Online (Sandbox Code Playgroud)

这种方法的优点是(1)是单行,(2)不需要效用函数,最重要的是(3)实际上不会改变数据帧中的任何数据。

警告:这是通过按降序对索引进行排序来工作的,因此对于任何给定的 Dataframe 可能并不总是合适或概括。