正确的方法来扭转一个PandasDataFrame?

2admgd59  于 2023-03-21  发布在  其他
关注(0)|答案(7)|浏览(156)

下面是我的代码:

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?**

zour9fqk

zour9fqk1#

data.reindex(index=data.index[::-1])

或者简单地说:

data.iloc[::-1]

将反转 Dataframe ,如果你想有一个从下到上的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。然后它试图在range(6, 0, -1)中为j调用data[j - 1],第一个调用将是data[5];但是在pandas中,dataframe data[5]表示第5列,并且没有第5列,因此它将抛出异常。

s6fujrry

s6fujrry2#

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

df[::-1]
9cbw7uwe

9cbw7uwe3#

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

TL;DR:df[::-1]

这是反转DataFrame的最佳方法,因为1)它是常量运行时间,即O(1)2)它是单个操作,3)简洁/可读(假设熟悉slice notation)。

长版本

我发现旧的切片技巧**df[::-1]**(或等效的df.loc[::-1] 1)是最简洁和惯用的反转DataFrame的方法。这反映了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)还是标签(loc)反转。

The Proof is in the Pudding

X轴表示数据集大小。Y轴表示反转所需的时间。没有方法可以像切片技巧一样缩放,它一直在图的底部。Benchmarking code供参考,使用perfplot生成的图。

其他解决方案点评

  • df.reindex(index=df.index[::-1])显然是一个流行的解决方案,但乍一看,对于不熟悉的读者来说,这段代码是“反转DataFrame”有多明显?此外,这是反转索引,然后使用中间结果到reindex,所以这本质上是一个两个步骤的操作(当它可能只是一个)。
  • df.sort_index(ascending=False)在大多数情况下都可以工作,如果你有一个简单的范围索引,但这假设你的索引是按升序排序的,所以不能很好地泛化。
  • 请不要使用iterrows。我看到一些建议反向迭代的选项。无论你的用例是什么,都可能有一个可用的向量化方法,但是如果没有,那么你可以使用一些更合理的方法,比如列表解析。请参阅如何在Pandas中迭代DataFrame中的行,以了解更多关于为什么iterrows是反模式的细节。
rryofs0p

rryofs0p4#

在反转 Dataframe 之后,现有答案都不重置索引。
为此,请执行以下操作:

data[::-1].reset_index()

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

def reset_my_index(df):
  res = df[::-1].reset_index(drop=True)
  return(res)

只需将 Dataframe 传入函数

nwo49xxi

nwo49xxi5#

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

data = data.sort_index(ascending=False)

这种方法具有以下优点:(1)是单行,(2)不需要效用函数,最重要的是(3)**实际上不更改 Dataframe 中的任何数据。
警告:这是通过按降序对索引进行排序来工作的,因此可能并不总是适合或适用于任何给定的数据框架。

5lwkijsr

5lwkijsr6#

这是可行的:

for i,r in data[::-1].iterrows():
        print(r['Odd'], r['Even'])
6pp0gazn

6pp0gazn7#

df = df.loc[reversed(df.index)]
这可能比负切片更明确,更不隐晦。

相关问题