为什么我的新列在使用.sample方法后会进行网络分配?

问题描述 投票:4回答:2

所以我只是回答了一个问题而且我遇到了一些有趣的事情:

数据框如下所示:

  string1 string2
0     abc     def
1     ghi     jkl
2     mno     pqr
3     stu     vwx

因此,当我执行以下操作时,新列的分配有效:

df['string3'] = df.string2

print(df)

  string1 string2 string3
0     abc     def     def
1     ghi     jkl     jkl
2     mno     pqr     pqr
3     stu     vwx     vwx

但是当我使用pandas.DataFrame.Series.sample时,新的列会分配net,至少不是sampled

df['string4'] = df.string2.sample(len(df.string2))
print(df)
  string1 string2 string3 string4
0     abc     def     def     def
1     ghi     jkl     jkl     jkl
2     mno     pqr     pqr     pqr
3     stu     vwx     vwx     vwx

所以我测试了一些东西:

Test1使用未分配的样本,给出正确的输出:

df.string2.sample(len(df.string2))

2    pqr
1    jkl
0    def
3    vwx
Name: string2, dtype: object

Test2无法覆盖:

df['string2'] = df.string2.sample(len(df.string2))
print(df)
  string1 string2
0     abc     def
1     ghi     jkl
2     mno     pqr
3     stu     vwx

这有效,但为什么呢?

df['string2'] = df.string2.sample(len(df.string2)).values
print(df)
  string1 string2
0     abc     jkl
1     ghi     def
2     mno     vwx
3     stu     pqr

为什么我需要明确使用.values.tolist()来分配正确?

python pandas dataframe sample
2个回答
4
投票

pandasindex敏感,这意味着他们检查indexassign它,这是当你做serise赋值,整个df没有改变,因为index没有改变,在sort_index后,它仍然显示相同的values顺序,但如果你做numpy array赋值,将不考虑index,因此值本身将被分配回原始的df,从而产生输出

边缘的一个例子

df['string3']=pd.Series(['aaa','aaa','aaa','aaa'],index=[100,111,112,113])
df
Out[462]: 
  string1 string2 string3
0     abc     vwx     NaN
1     ghi     jkl     NaN
2     mno     dfe     NaN
3     stu     pqr     NaN

当你使用.loc进行条件赋值时,因为该索引敏感

你总能这样做

df.loc[df.condition,'value']=df.value*100 
# since the not selected one will not be change 

与你用np.where做的一样

df['value']=np.where(df.condition,df.value*100 ,df.value)

其他一些用例,当我做groupby apply与none-agg功能并尝试将其分配回来,为什么它失败

df['String4']=df.groupby('string1').apply(lambda x :x['string2']+'aa')

TypeError:带有帧索引的插入列的不兼容索引

让我们试着看看groupby.apply的回归

df.groupby('string1').apply(lambda x : x['string2']+'aa')
Out[466]: 
string1   
abc      0    vwxaa
ghi      1    jklaa
mno      2    dfeaa
stu      3    pqraa
Name: string2, dtype

请注意,它在索引中添加了一个级别,因此返回是多个索引,而原始df只有一个维度,这将导致错误消息。


怎么解决?


reset index并使用原始索引,这是groupby产品的第二级,然后将其分配回来

df['String4']=df.groupby('string1').apply(lambda x : x['string2']+'aa').reset_index(level=0,drop=True)
df
Out[469]: 
  string1 string2 string3 String4
0     abc     vwx     NaN   vwxaa
1     ghi     jkl     NaN   jklaa
2     mno     dfe     NaN   dfeaa
3     stu     pqr     NaN   pqraa

正如Erfan在评论中提到的那样,我们怎么能意外地将不需要的价值分配给pandas.DataFrame

两种不同的分配方式。

1,带有数组或列表或元组..无法对齐,这意味着当df和assign对象之间的长度不同时,它将失败

第二次分配pandas object,总是对齐,没有错误会返回,甚至长度不同

但是,当assign对象具有重复索引时,它将引发错误

df['string3']=pd.Series(['aaa','aaa','aaa','aaa'],index=[100,100,100,100])
ValueError: cannot reindex from a duplicate axis

3
投票

那是因为索引仍然相同,请尝试使用reset_index

df.string2=df.string2.sample(len(df.string2)).reset_index(drop=True)
print(df)

  string1 string2
0     abc     jkl
1     ghi     pqr
2     mno     vwx
3     stu     vwx

另一方面,.values只有没有索引的值,因此有效

© www.soinside.com 2019 - 2024. All rights reserved.