熊猫-获取给定列的第一行值


299

这似乎是一个非常简单的问题……但是我没有看到我期望的简单答案。

那么,如何获得Pandas中给定列的第n行的值?(我对第一行特别感兴趣,但也对更通用的做法感兴趣)。

例如,假设我想将Btime中的1.2值作为变量。

什么是正确的方法?

df_test =

  ATime   X   Y   Z   Btime  C   D   E
0    1.2  2  15   2    1.2  12  25  12
1    1.4  3  12   1    1.3  13  22  11
2    1.5  1  10   6    1.4  11  20  16
3    1.6  2   9  10    1.7  12  29  12
4    1.9  1   1   9    1.9  11  21  19
5    2.0  0   0   0    2.0   8  10  11
6    2.4  0   0   0    2.4  10  12  15

7
如果您只是想让第一行df_test.head(1)工作,可以使用更通用的形式,iloc由unutbu回答
EdChum 2014年

1
您是否只想要价值1.2?或您获得的长度为1的系列df_test.head(1),其中还包含索引?要仅获取值,请执行df_test.head(1).item()tolist()然后切片。
smci

Answers:


469

要选择该ith行,请使用iloc

In [31]: df_test.iloc[0]
Out[31]: 
ATime     1.2
X         2.0
Y        15.0
Z         2.0
Btime     1.2
C        12.0
D        25.0
E        12.0
Name: 0, dtype: float64

要在Btime列中选择第i个值,可以使用:

In [30]: df_test['Btime'].iloc[0]
Out[30]: 1.2

df_test['Btime'].iloc[0](推荐)和之间有区别df_test.iloc[0]['Btime']

DataFrames将数据存储在基于列的块中(每个块具有一个dtype)。如果先按列选择,则可以返回视图(比返回副本要快),并且保留原始dtype。相反,如果首先选择按行,并且DataFrame的列具有不同的dtype,则Pandas 将数据复制到新的Object dtype 系列中。因此,选择列比选择行要快一些。因此,虽然 df_test.iloc[0]['Btime']作品,df_test['Btime'].iloc[0]是多一点点效率。

在分配方面,两者之间存在很大差异。 df_test['Btime'].iloc[0] = x影响df_test,但df_test.iloc[0]['Btime'] 可能不会。有关原因的说明,请参见下文。由于索引顺序的细微差别会在行为上产生很大差异,因此最好使用单个索引分配:

df.iloc[0, df.columns.get_loc('Btime')] = x

df.iloc[0, df.columns.get_loc('Btime')] = x (推荐的):

为DataFrame分配新值的推荐方法避免链接索引,而应使用andrew所示的方法,

df.loc[df.index[n], 'Btime'] = x

要么

df.iloc[n, df.columns.get_loc('Btime')] = x

后一种方法要快一些,因为df.loc必须将行和列标签转换为位置索引,因此,如果使用df.iloc替代方法,则转换的必要性要少一些 。


df['Btime'].iloc[0] = x 可行,但不建议:

尽管这可行,但是它利用了当前实现DataFrames的方式。不能保证熊猫将来会以这种方式工作。特别是,它利用了以下事实:(当前)df['Btime']始终返回视图(而不是副本),因此df['Btime'].iloc[n] = x可用于在的列的第n个位置分配新值。Btimedf

由于Pandas无法明确保证索引器何时返回视图还是副本,因此使用链式索引的赋值通常会引发,SettingWithCopyWarning即使在这种情况下,赋值可以成功修改df

In [22]: df = pd.DataFrame({'foo':list('ABC')}, index=[0,2,1])
In [24]: df['bar'] = 100
In [25]: df['bar'].iloc[0] = 99
/home/unutbu/data/binky/bin/ipython:1: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  self._setitem_with_indexer(indexer, value)

In [26]: df
Out[26]: 
  foo  bar
0   A   99  <-- assignment succeeded
2   B  100
1   C  100

df.iloc[0]['Btime'] = x 不起作用:

相比之下,with的分配df.iloc[0]['bar'] = 123不起作用,因为df.iloc[0]正在返回副本:

In [66]: df.iloc[0]['bar'] = 123
/home/unutbu/data/binky/bin/ipython:1: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy

In [67]: df
Out[67]: 
  foo  bar
0   A   99  <-- assignment failed
2   B  100
1   C  100

警告:我之前曾建议过df_test.ix[i, 'Btime']。但这不能保证为您提供ith值,因为在尝试按位置索引之前先尝试ix标签索引。因此,如果DataFrame的整数索引不是从0开始的排序顺序,则using 将返回标有标签的行,而不是该行。例如,ix[i] iith

In [1]: df = pd.DataFrame({'foo':list('ABC')}, index=[0,2,1])

In [2]: df
Out[2]: 
  foo
0   A
2   B
1   C

In [4]: df.ix[1, 'foo']
Out[4]: 'C'

1
@CristianCiupitu:DataFrames将数据存储在基于列的块中(每个块具有一个dtype)。如果先按列选择,则可以返回视图(比返回副本要快),并且保留原始dtype。相反,如果首先选择按行,并且DataFrame的列具有不同的dtype,则Pandas 将数据复制到新的Object dtype 系列中。因此,选择列比选择行要快一些。因此,虽然df_test.iloc[0]['Btime']作品,df_test.iloc['Btime'][0]是多一点点效率。
unutbu

@unutbu,df['Btime'].iloc[0]首选df['Btime'].values[0]?我从文档中看到“警告:我们建议使用Series.array或Series.to_numpy(),具体取决于您需要引用基础数据还是NumPy数组。” 但我不确定这到底是什么意思
aydow

28

请注意,@ unutbu的答案是正确的,直到您想将值设置为新值,否则如果您的数据框是视图,则该答案将不起作用。

In [4]: df = pd.DataFrame({'foo':list('ABC')}, index=[0,2,1])
In [5]: df['bar'] = 100
In [6]: df['bar'].iloc[0] = 99
/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pandas-0.16.0_19_g8d2818e-py2.7-macosx-10.9-x86_64.egg/pandas/core/indexing.py:118: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame

See the the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  self._setitem_with_indexer(indexer, value)

可以同时在设置和获取上使用的另一种方法是:

In [7]: df.loc[df.index[0], 'foo']
Out[7]: 'A'
In [8]: df.loc[df.index[0], 'bar'] = 99
In [9]: df
Out[9]:
  foo  bar
0   A   99
2   B  100
1   C  100

1
我正在遍历一堆.csv文件,并在每个文件中读取某个列的第一个值。由于某些我无法解释的原因,而不是返回值,这有时会返回索引以及使处理混乱的值。我求助于df.col.unique()[0]。
麻雀

15

另一种方法是:

first_value = df['Btime'].values[0]

这种方式似乎比使用更快.iloc

In [1]: %timeit -n 1000 df['Btime'].values[20]
5.82 µs ± 142 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [2]: %timeit -n 1000 df['Btime'].iloc[20]
29.2 µs ± 1.28 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

12
  1. df.iloc[0].head(1) -仅从整个第一行开始的第一个数据集。
  2. df.iloc[0] -整个列的第一行。

8

通常,如果您想从J列中获取前N行,最好的方法是:pandas dataframe

data = dataframe[0:N][:,J]

2
@anis:为此,我相信您最好写一个新问题,寻求更一般的解决方案,然后自己回答。
jonathan.scholbach

3

为了从列“ test”和第1行获取例如值,它的工作原理如下

df[['test']].values[0][0]

因为只df[['test']].values[0]给一个数组


1

获取第一行并保留索引的另一种方法:

x = df.first('d') # Returns the first day. '3d' gives first three days.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.