簡體   English   中英

Pandas通過布爾“loc”和后續的“iloc”進行索引

[英]Pandas indexing by both boolean `loc` and subsequent `iloc`

我想使用布爾掩碼索引Pandas數據幀,然后根據整數索引在過濾后的數據幀的子集中設置一個值,並將此值反映在數據幀中。 也就是說,如果這對數據框架有所了解,我會很高興。

例:

In [293]:

df = pd.DataFrame({'a': [0, 1, 2, 3, 4, 5, 6, 7],
                   'b': [5, 5, 2, 2, 5, 5, 2, 2],
                   'c': [0, 0, 0, 0, 0, 0, 0, 0]})

mask = (df['a'] < 7) & (df['b'] == 2)
df.loc[mask, 'c']

Out[293]:
2    0
3    0
6    0
Name: c, dtype: int64

現在我想設置過濾后的數據幀中返回的前兩個元素的值。 iloc鏈接到上面的loc調用上可以編制索引:

In [294]:

df.loc[mask, 'c'].iloc[0: 2]

Out[294]:

2    0
3    0
Name: c, dtype: int64

但不要分配:

In [295]:

df.loc[mask, 'c'].iloc[0: 2] = 1

print(df)

   a  b  c
0  0  5  0
1  1  5  0
2  2  2  0
3  3  2  0
4  4  5  0
5  5  5  0
6  6  2  0
7  7  2  0

使賦值與切片的長度相同(即= [1, 1] )也不起作用。 有沒有辦法分配這些值?

這確實有效但有點難看,基本上我們使用從掩碼生成的索引並對loc進行額外調用:

In [57]:

df.loc[df.loc[mask,'c'].iloc[0:2].index, 'c'] = 1
df
Out[57]:
   a  b  c
0  0  5  0
1  1  5  0
2  2  2  1
3  3  2  1
4  4  5  0
5  5  5  0
6  6  2  0
7  7  2  0

所以突破以上:

In [60]:
# take the index from the mask and iloc
df.loc[mask, 'c'].iloc[0: 2]
Out[60]:
2    0
3    0
Name: c, dtype: int64
In [61]:
# call loc using this index, we can now use this to select column 'c' and set the value
df.loc[df.loc[mask,'c'].iloc[0:2].index]
Out[61]:
   a  b  c
2  2  2  0
3  3  2  0

怎么樣。

ix = df.index[mask][:2]
df.loc[ix, 'c'] = 1

與EdChum相同的想法,但在評論中建議更優雅。

編輯:必須要小心這個,因為它可能會給出一個非唯一索引的不需要的結果,因為可能有多行由上面的ix的任何一個標簽索引。 如果索引是非唯一的並且您只想要滿足布爾鍵的前2行(或n行),那么使用帶有整數索引的.iloc會更安全

ix = np.where(mask)[0][:2]
df.iloc[ix, 'c'] = 1

我不知道這是否更優雅,但它有點不同:

mask = mask & (mask.cumsum() < 3)

df.loc[mask, 'c'] = 1

   a  b  c
0  0  5  0
1  1  5  0
2  2  2  1
3  3  2  1
4  4  5  0
5  5  5  0
6  6  2  0
7  7  2  0

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM