为什么我的新列在使用 .sample 方法后没有被分配?

Why does my new column does net get assigned after using .sample method?

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

数据框如下所示:

  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

测试2 无法覆盖:

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() 才能正确分配?

那是因为索引还是一样,用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 只有没有索引的值,因此可以工作

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

egde的例子

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)

一些其他用例 当我使用 none-agg 函数执行 groupby apply 并尝试将其分配回来时,为什么失败

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

TypeError: incompatible index of inserted column with frame index

让我们试着看看 groupby.apply return

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

注意这里多加了一层索引,所以return是多索引,原来的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

两种不同的赋值方式。

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

第二次赋值 pandas object,始终对齐,不会出错 return,即使长度不同

但是当赋值对象有重复索引时,会报错

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