索引Pandas数据帧:整数行,命名列

Hil*_*ers 36 python dataframe pandas

Say df是一个熊猫数据帧.

  • df.loc[] 只接受名字
  • df.iloc[] 只接受整数(实际展示位置)
  • df.ix[] 接受名称和整数:

引用行时,df.ix[row_idx, ]只想获得名称.例如

df = pd.DataFrame({'a' : ['one', 'two', 'three','four', 'five', 'six'],
                   '1' : np.arange(6)})
df = df.ix[2:6]
print(df)

   1      a
2  2  three
3  3   four
4  4   five
5  5    six

df.ix[0, 'a']
Run Code Online (Sandbox Code Playgroud)

抛出错误,它不会返回'两个'.

在引用列时,iloc更喜欢整数,而不是名称.例如

df.ix[2, 1]
Run Code Online (Sandbox Code Playgroud)

返回'三',而不是2.(虽然df.idx[2, '1']确实返回2).

奇怪的是,我想要完全相反的功能.通常我的列名非常有意义,所以在我的代码中我直接引用它们.但是由于大量的观察清理,我的pandas数据框中的行名通常不对应range(len(df)).

我意识到我可以使用:

df.iloc[0].loc['a'] # returns three
Run Code Online (Sandbox Code Playgroud)

但它看起来很难看!有没有人知道更好的方法来做到这一点,所以代码看起来像这样?

df.foo[0, 'a'] # returns three
Run Code Online (Sandbox Code Playgroud)

事实上,是否有可能将自己的新方法添加到pandas.core.frame.DataFrames,所以例如 df.idx(rows, cols)实际上是df.iloc[rows].loc[cols]

bru*_*ton 34

这是一个迟到的答案,但@ unutbu的评论仍然有效,是解决这个问题的一个很好的解决方案.

要使用整数行和命名列(标记为列)索引DataFrame:

df.loc[df.index[#], 'NAME']where #是有效的整数索引,NAME是列的名称.

  • 您的方法要求索引中的值是唯一的。否则它将返回一个带有所有匹配索引“#”的系列 (4认同)

Ben*_*Ben 21

现有的答案对我来说似乎是短视的。

有问题的解决方案

  1. df.loc[df.index[0], 'a']
    这里的策略是获取第0行的行标签,然后.loc正常使用。我看到两个问题。

    1. 如果 df 有重复的行标签,则df.loc[df.index[0], 'a']可能返回多行。
    2. .loc.iloc你在这里牺牲速度慢。
  2. df.reset_index(drop=True).loc[0, 'a']
    这里的策略是重置索引,使行标签变为 0, 1, 2, ... 从而.loc[0]给出与 相同的结果.iloc[0]。不过,这里的问题是运行时,因为.loc它比它慢,.iloc并且您将产生重置索引的成本。

更好的解决方案

我建议遵循@Landmaster 的评论

df.iloc[0, df.columns.get_loc("a")]
Run Code Online (Sandbox Code Playgroud)

本质上,这与df.iloc[0, 0]我们使用 动态获取列索引相同df.columns.get_loc("a")

要索引多个列,例如['a', 'b', 'c'],请使用:

df.iloc[0, [df.columns.get_loc(c) for c in ['a', 'b', 'c']]]
Run Code Online (Sandbox Code Playgroud)

更新

这是讨论在这里为我的一部分,对熊猫课程

  • 您的首选解决方案 `df.iloc[0, df.columns.get_loc("a")]` 不能免除重复标签,因为列标签也可以重复。所以你什么也得不到,但它比“df.loc[df.index[0], 'a']”更冗长、更慢。对于单值访问,无论如何您都不应该使用它们。 (3认同)

Dar*_*aut 9

要获取或设置按行/列标签中的单个DataFrame值,您最好使用DataFrame.at而不是DataFrame.loc, 因为它是...

\n\n
    \n
  1. 快点
  2. \n
  3. 您更明确地只想访问单个值。
  4. \n
\n\n

其他人已经展示过,如果您从行的整数位置开始,您仍然必须首先使用DataFrame.indexas找到行标签DataFrame.at接受标签:

\n\n
df.at[df.index[0], \'a\']\n# Out: \'three\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

基准:

\n\n
%timeit df.at[df.index[0], \'a\']\n# 7.57 \xc2\xb5s \xc2\xb1 30.8 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 100000 loops each)\n%timeit df.loc[df.index[0], \'a\']\n# 10.9 \xc2\xb5s \xc2\xb1 53.3 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 100000 loops each)\n%timeit df.iloc[0, df.columns.get_loc("a")]\n# 13.3 \xc2\xb5s \xc2\xb1 24 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 100000 loops each)\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

为了完整性:

\n\n

DataFrame.iat用于按整数位置访问行/列对的单个值。

\n


Kri*_*hna 6

我们可以重置索引,然后像这样使用基于0的索引

df.reset_index(drop=True).loc[0,'a']

编辑:[]从列名索引中删除,'a'因此它只输出值


Cod*_*ent 5

一个很晚的答案,但让我惊讶的是,这些年来熊猫仍然没有这样的功能。如果它让你很恼火,你可以在 DataFrame 中添加一个自定义索引器:

class XLocIndexer:
    def __init__(self, frame):
        self.frame = frame
    
    def __getitem__(self, key):
        row, col = key
        return self.frame.iloc[row][col]

pd.core.indexing.IndexingMixin.xloc = property(lambda frame: XLocIndexer(frame))

# Usage
df.xloc[0, 'a'] # one
Run Code Online (Sandbox Code Playgroud)