Pandas 索引,在数据框中搜索
Pandas indexing, searching in dataframes
问题已解决
使用 loc
而不是 iloc
可以解决问题,但我不确定为什么。
中等大小的数据帧 (80766, 19),由整数、浮点数和日期组成。
在我工作的时候,我注意到我的结果很奇怪。
我开始对表达式进行改造和简化,看看问题出在哪里,结果陷入了矛盾
使用这两行我得到了相同的结果(如预期的那样):
import pandas
...
data_table[data_table[col_name] == 69][col_name]
data_table.iloc[data_table.index[data_table[col_name] == 69]][col_name]
结果:
23270 69
23271 69
..
25059 69
Name: BBCH, Length: 1790, dtype: int64
但是当我将搜索值更改为更高时,第二行给出了完全错误的结果。
data_table[data_table[col_name] == 71][col_name]
结果不错:
39556 71
39557 71
..
41353 71
Name: BBCH, Length: 1798, dtype: int64
而对于
data_table.iloc[data_table.index[data_table[col_name] == 71]][col_name]
结果是:
7336 30
7337 30
..
9133 30
Name: BBCH, Length: 1798, dtype: int64
我的问题是为什么会这样?是不是数据量的问题?
只要您的索引是 RangeIndex
,即没有间隙,您就可以交替使用 loc
和 iloc
,例如
>>> s = pd.Series('foo', index=range(10))
>>> s
0 foo
1 foo
2 foo
3 foo
4 foo
5 foo
6 foo
7 foo
8 foo
9 foo
dtype: object
>>> s.loc[[1, 2, 7]]
1 foo
2 foo
7 foo
dtype: object
>>> s.iloc[[1, 2, 7]]
1 foo
2 foo
7 foo
dtype: object
但是 s.loc[[1, 2, 7]]
select 是 标记为 1
、2
和 7
的行,无论它们的位置如何,而 iloc
提取位于 位置 索引 1
、2
和 7
的行。如果您更改 s
中行的顺序,loc
仍会给出相同的行,但 iloc
会给出第二行、第三行和第八行的任何内容。
如果您修改数据使其不再是 RangeIndex
(即,如果您愿意,则缺少行),loc
和 iloc
将给出不同的结果select “缺失行”之后的内容。因此,在下面的示例中,使用修改后的 s
,索引 1
和 2
处的行仍标记为 1
和 2
,因此它们是 select 由 loc
和 iloc
编辑,但第 8 行不再标记为 7
,而是 9
(因为我们删除了中间的两行)。
>>> s = s.drop([3, 4])
>>> s
0 foo # position = 0
1 foo # 1
2 foo # 2
5 foo # 3 but label == 5!!
6 foo # 4 but label == 6
7 foo # etc.
8 foo
9 foo
dtype: object
>>> s.loc[[1, 2, 7]]
1 foo
2 foo
7 foo
dtype: object
>>> s.iloc[[1, 2, 7]]
1 foo
2 foo
9 foo # != 7 !!
dtype: object
这解释了为什么在第一种情况下,您的结果是正确的,但在第二种情况下,某些原因导致索引的标签与位置值“不同步”(可能是一些丢失的行)。当您通过 .index
的 标签 子集进行 select 编辑时,您需要 loc
,而不是 iloc
。 (如果您在子集化之前执行 reset_index
,iloc
将再次起作用,因为索引将再次与行的位置相同。)
问题已解决
使用 loc
而不是 iloc
可以解决问题,但我不确定为什么。
中等大小的数据帧 (80766, 19),由整数、浮点数和日期组成。 在我工作的时候,我注意到我的结果很奇怪。 我开始对表达式进行改造和简化,看看问题出在哪里,结果陷入了矛盾
使用这两行我得到了相同的结果(如预期的那样):
import pandas
...
data_table[data_table[col_name] == 69][col_name]
data_table.iloc[data_table.index[data_table[col_name] == 69]][col_name]
结果:
23270 69
23271 69
..
25059 69
Name: BBCH, Length: 1790, dtype: int64
但是当我将搜索值更改为更高时,第二行给出了完全错误的结果。
data_table[data_table[col_name] == 71][col_name]
结果不错:
39556 71
39557 71
..
41353 71
Name: BBCH, Length: 1798, dtype: int64
而对于
data_table.iloc[data_table.index[data_table[col_name] == 71]][col_name]
结果是:
7336 30
7337 30
..
9133 30
Name: BBCH, Length: 1798, dtype: int64
我的问题是为什么会这样?是不是数据量的问题?
只要您的索引是 RangeIndex
,即没有间隙,您就可以交替使用 loc
和 iloc
,例如
>>> s = pd.Series('foo', index=range(10))
>>> s
0 foo
1 foo
2 foo
3 foo
4 foo
5 foo
6 foo
7 foo
8 foo
9 foo
dtype: object
>>> s.loc[[1, 2, 7]]
1 foo
2 foo
7 foo
dtype: object
>>> s.iloc[[1, 2, 7]]
1 foo
2 foo
7 foo
dtype: object
但是 s.loc[[1, 2, 7]]
select 是 标记为 1
、2
和 7
的行,无论它们的位置如何,而 iloc
提取位于 位置 索引 1
、2
和 7
的行。如果您更改 s
中行的顺序,loc
仍会给出相同的行,但 iloc
会给出第二行、第三行和第八行的任何内容。
如果您修改数据使其不再是 RangeIndex
(即,如果您愿意,则缺少行),loc
和 iloc
将给出不同的结果select “缺失行”之后的内容。因此,在下面的示例中,使用修改后的 s
,索引 1
和 2
处的行仍标记为 1
和 2
,因此它们是 select 由 loc
和 iloc
编辑,但第 8 行不再标记为 7
,而是 9
(因为我们删除了中间的两行)。
>>> s = s.drop([3, 4])
>>> s
0 foo # position = 0
1 foo # 1
2 foo # 2
5 foo # 3 but label == 5!!
6 foo # 4 but label == 6
7 foo # etc.
8 foo
9 foo
dtype: object
>>> s.loc[[1, 2, 7]]
1 foo
2 foo
7 foo
dtype: object
>>> s.iloc[[1, 2, 7]]
1 foo
2 foo
9 foo # != 7 !!
dtype: object
这解释了为什么在第一种情况下,您的结果是正确的,但在第二种情况下,某些原因导致索引的标签与位置值“不同步”(可能是一些丢失的行)。当您通过 .index
的 标签 子集进行 select 编辑时,您需要 loc
,而不是 iloc
。 (如果您在子集化之前执行 reset_index
,iloc
将再次起作用,因为索引将再次与行的位置相同。)