Rex*_*zle 14 python mask slice pandas argmax
所以我想制作一个数据帧片,然后设置该片中第一个项的值而不复制数据帧.例如:
df = pandas.DataFrame(numpy.random.rand(3,1))
df[df[0]>0][0] = 0
Run Code Online (Sandbox Code Playgroud)
这里的切片是无关紧要的,仅用于示例,并将再次返回整个数据帧.重点是,通过这样做,就像在示例中,您获得了带有复制警告的设置(可以理解).我还尝试先切片,然后使用ILOC/IX/LOC并使用ILOC两次,例如:
df.iloc[df[0]>0,:][0] = 0
df[df[0]>0,:].iloc[0] = 0
Run Code Online (Sandbox Code Playgroud)
这些都不起作用.再次 - 我不想复制数据框,即使它只是切片版本.
编辑:似乎有两种方法,使用掩码或IdxMax.如果索引是唯一的,IdxMax方法似乎有效,如果不是,则掩码方法.在我的情况下,索引不是唯一的,我在最初的帖子中忘了提到.
jez*_*ael 13
我认为你可以使用idxmax获取第一个True值的索引然后设置loc:
np.random.seed(1)
df = pd.DataFrame(np.random.randint(4, size=(5,1)))
print (df)
0
0 1
1 3
2 0
3 0
4 3
print ((df[0] == 0).idxmax())
2
df.loc[(df[0] == 0).idxmax(), 0] = 100
print (df)
0
0 1
1 3
2 100
3 0
4 3
Run Code Online (Sandbox Code Playgroud)
df.loc[(df[0] == 3).idxmax(), 0] = 200
print (df)
0
0 1
1 200
2 0
3 0
4 3
Run Code Online (Sandbox Code Playgroud)
编辑:
解决方案没有唯一索引:
np.random.seed(1)
df = pd.DataFrame(np.random.randint(4, size=(5,1)), index=[1,2,2,3,4])
print (df)
0
1 1
2 3
2 0
3 0
4 3
df = df.reset_index()
df.loc[(df[0] == 3).idxmax(), 0] = 200
df = df.set_index('index')
df.index.name = None
print (df)
0
1 1
2 200
2 0
3 0
4 3
Run Code Online (Sandbox Code Playgroud)
EDIT1:
解决方案MultiIndex:
np.random.seed(1)
df = pd.DataFrame(np.random.randint(4, size=(5,1)), index=[1,2,2,3,4])
print (df)
0
1 1
2 3
2 0
3 0
4 3
df.index = [np.arange(len(df.index)), df.index]
print (df)
0
0 1 1
1 2 3
2 2 0
3 3 0
4 4 3
df.loc[(df[0] == 3).idxmax(), 0] = 200
df = df.reset_index(level=0, drop=True)
print (df)
0
1 1
2 200
2 0
3 0
4 3
Run Code Online (Sandbox Code Playgroud)
EDIT2:
双重解决方案cumsum:
np.random.seed(1)
df = pd.DataFrame([4,0,4,7,4], index=[1,2,2,3,4])
print (df)
0
1 4
2 0
2 4
3 7
4 4
mask = (df[0] == 0).cumsum().cumsum()
print (mask)
1 0
2 1
2 2
3 3
4 4
Name: 0, dtype: int32
df.loc[mask == 1, 0] = 200
print (df)
0
1 4
2 200
2 4
3 7
4 4
Run Code Online (Sandbox Code Playgroud)
因此,使用一些答案,我设法找到了一种单行方法来做到这一点:
np.random.seed(1)
df = pd.DataFrame(np.random.randint(4, size=(5,1)))
print df
0
0 1
1 3
2 0
3 0
4 3
df.loc[(df[0] == 0).cumsum()==1,0] = 1
0
0 1
1 3
2 1
3 0
4 3
Run Code Online (Sandbox Code Playgroud)
本质上,这是使用与 cumsum 内联的掩码。