为什么在使用.sample方法后,net会分配给我的新列?

时间:2019-03-28 15:50:45

标签: python pandas dataframe sample

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

数据框如下所示:

  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时,新列确实被分配,至少没有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

所以我测试了一些东西:

测试1 使用没有分配的样本,将为我们提供正确的输出:

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()来获得正确的分配?

2 个答案:

答案 0 :(得分:4)

Symbol.iteratorpandas敏感的,这意味着他们会在index时检查index,也就是说,当您进行assign分配时,整个df不变,因为serise不变,在index之后,它仍然显示sort_index相同的顺序,但是如果您执行values numpy分配,则不会考虑array,因此会将值本身分配回原始index,从而产生输出

egde的例子

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

其他一些用例 当我使用none-agg函数执行df['value']=np.where(df.condition,df.value*100 ,df.value) groupby并尝试将其分配回时,为什么会失败

  

apply

     

TypeError:插入的列的索引与框架索引不兼容

让我们尝试看看df['String4']=df.groupby('string1').apply(lambda x :x['string2']+'aa')的返回

groupby.apply

请注意,此处它在索引中增加了一层,因此返回的是多个索引,原始df仅具有一维,这将导致错误消息。


如何修复?


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 reset并使用index产品第二级的原始索引,然后将其分配回

groupby

正如Erfan在评论中所提到的,我们如何禁止意外地将不必要的值分配给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

两种不同的assign方式。

第一个,带有数组,列表或元组.. CANNOT ALIGN,这意味着当df和分配对象之间的长度不同时,它将失败

使用pandas.DataFrame pandas进行第二次分配,始终对齐,即使长度不同,也不会返回错误

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

object

答案 1 :(得分: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仅具有不带索引的值,因此可以正常工作