获取Pandas DataFrame的第一列

17
假设有一个简单的数据框:
import pandas as pd
a = pd.DataFrame([[0,1], [2,3]])

我可以很容易地切割这个数据框,第一列是a [[0]],第二列是a [[1]]

现在,让我们来看更复杂的数据框。下面是我的代码的一部分:

frame = pd.DataFrame(range(100), columns=["Variable"], index=["_".join(["loc", str(i)]) for i in range(1, 101)])
frame[1] = [i**3 for i in range(100)]

DataFrame frame 也是一个 pandas DataFrame。我可以通过 frame[[1]] 获取第二列。但是当我尝试使用 frame[[0]] 时,会出现错误:

Traceback (most recent call last):

  File "<ipython-input-55-0c56ffb47d0d>", line 1, in <module>
    frame[[0]]

  File "C:\Users\Robert\Desktop\Záloha\WinPython-64bit-3.5.2.2\python-    3.5.2.amd64\lib\site-packages\pandas\core\frame.py", line 1991, in __getitem__
    return self._getitem_array(key)

  File "C:\Users\Robert\Desktop\Záloha\WinPython-64bit-3.5.2.2\python-    3.5.2.amd64\lib\site-packages\pandas\core\frame.py", line 2035, in     _getitem_array
    indexer = self.ix._convert_to_indexer(key, axis=1)

  File "C:\Users\Robert\Desktop\Záloha\WinPython-64bit-3.5.2.2\python-    3.5.2.amd64\lib\site-packages\pandas\core\indexing.py", line 1184, in     _convert_to_indexer
    indexer = labels._convert_list_indexer(objarr, kind=self.name)

  File "C:\Users\Robert\Desktop\Záloha\WinPython-64bit-3.5.2.2\python-    3.5.2.amd64\lib\site-packages\pandas\indexes\base.py", line 1112, in     _convert_list_indexer
    return maybe_convert_indices(indexer, len(self))

  File "C:\Users\Robert\Desktop\Záloha\WinPython-64bit-3.5.2.2\python-    3.5.2.amd64\lib\site-packages\pandas\core\indexing.py", line 1856, in     maybe_convert_indices
    raise IndexError("indices are out-of-bounds")

IndexError: indices are out-of-bounds

我仍然可以使用frame.iloc[:,0],但问题是为什么我不能使用简单的切片[[]]?我使用的是WinPython Spyder 3。


3
在第一个DataFrame中可以正常工作,因为它有一个名为“0”的列。它碰巧是第一列,但不一定非要是第一列,可能是任何其他具有相同名称的列。因此,为了使用相同的内容,您需要通过名称访问(假设您想返回一个DataFrame而不是Series,则使用frame[['Variable']])。 - ayhan
2个回答

19

使用您的代码:

import pandas as pd

var_vec = [i for i in range(100)]
num_of_sites = 100
row_names = ["_".join(["loc", str(i)]) for i in 
             range(1,num_of_sites + 1)]
frame = pd.DataFrame(var_vec, columns = ["Variable"], index = row_names)
spec_ab = [i**3 for i in range(100)]
frame[1] = spec_ab

如果您要求打印“frame”,则会得到:

    Variable    1
loc_1   0       0
loc_2   1       1
loc_3   2       8
loc_4   3       27
loc_5   4       64
loc_6   5       125
......

因此,你的问题的原因变得很明显,你没有一个名为'0'的列。 在第1行,你指定了一个名为var_vec的列表。 在第4行,你从该列表创建一个数据帧,但你指定了索引值和列名(这通常是一个好习惯)。 数值列名'0'、'1'等只在你不指定列名时出现,它不是一个列位置索引器。

如果你想通过它们的位置访问列,可以使用以下方法:

df[df.columns[0]]

接下来发生的是,您获取数据框的列列表,然后选择术语“0”并将其作为参考传递给数据框。

希望这可以帮助您理解。

编辑:

另一种更好的方法是:

df.iloc[:,0]

“:”代表所有行(也可以用0到行数的数字进行索引)。


7
另一个选项是:df.iloc[:, 0] - IanS
1
df[df.columns[0]] will break when the df have more columns with same name of the cloumn[0] - kehao

0

[] 是对 __getitem__() 的包装器,它通过标签进行选择,正如 @epattaro 所解释的那样,在 OP 中创建的数据框中没有列标签 0。要按位置选择列(或行),规范的方法是使用 iloc

df.iloc[:, 0]         # select first column as a Series
df.iloc[:, [0]]       # select first column as a single column DataFrame

df.iloc[0]            # select first row as a Series
df.iloc[[0]]          # select first row as a single row DataFrame

另一种方法是take():
df.take([0], axis=1)  # select first column
df.take([0])          # select first row

您可以验证对于任何dfdf.take([0], axis=1).equals(df.iloc[:, [0]])都会返回True。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接