在pandas中一起使用loc和iloc

Ale*_*lex 9 python indexing dataframe pandas

说我有以下的数据帧,我想改变列的两个元素c是对应于列前两个元素a是等于1平等2.

>>> df = pd.DataFrame({"a" : [1,1,1,1,2,2,2,2], "b" : [2,3,1,4,5,6,7,2], "c" : [1,2,3,4,5,6,7,8]})
>>> df.loc[df["a"] == 1, "c"].iloc[0:2] = 2
>>> df
   a  b  c
0  1  2  1
1  1  3  2
2  1  1  3
3  1  4  4
4  2  5  5
5  2  6  6
6  2  7  7
7  2  2  8
Run Code Online (Sandbox Code Playgroud)

第二行中的代码不起作用,因为iloc设置了副本,因此不修改原始数据帧.我该怎么做?

ayh*_*han 5

一种肮脏的方式是:

df.loc[df[df['a'] == 1][:2].index, 'c'] = 2
Run Code Online (Sandbox Code Playgroud)

  • 我能够保存一个字符:`df.loc[df.index[df.a == 1][:2], 'c'] = 2` (4认同)
  • 我不认为这很脏!这是一类切片的示例,其中它沿着一个轴定位,并在另一个轴上通过索引。 (2认同)

jez*_*ael 2

您可以使用Index.isin

import pandas as pd

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

#more general index                       
df.index = df.index + 10
print (df)
    a  b  c
10  1  2  1
11  1  3  2
12  1  1  3
13  1  4  4
14  2  5  5
15  2  6  6
16  2  7  7
17  2  2  8

print (df.index.isin(df.index[:2]))
[ True  True False False False False False False]

df.loc[(df["a"] == 1) & (df.index.isin(df.index[:2])), "c"] = 2
print (df)
    a  b  c
10  1  2  2
11  1  3  2
12  1  1  3
13  1  4  4
14  2  5  5
15  2  6  6
16  2  7  7
17  2  2  8
Run Code Online (Sandbox Code Playgroud)

如果索引是nice(从没有重复项开始0):

df.loc[(df["a"] == 1) & (df.index < 2), "c"] = 2
print (df)
   a  b  c
0  1  2  2
1  1  3  2
2  1  1  3
3  1  4  4
4  2  5  5
5  2  6  6
6  2  7  7
7  2  2  8
Run Code Online (Sandbox Code Playgroud)

另一个解决方案:

mask = df["a"] == 1
mask = mask & (mask.cumsum() < 3)

df.loc[mask.index[:2], "c"] = 2
print (df)
   a  b  c
0  1  2  2
1  1  3  2
2  1  1  3
3  1  4  4
4  2  5  5
5  2  6  6
6  2  7  7
7  2  2  8
Run Code Online (Sandbox Code Playgroud)