筛选部分数据后,并把它们赋值到另外一筛选数据中,可能出现错位或者缺失值的情况。并报SettingWithCopyWarning
import pandas as pd
A = pd.DataFrame({'a': range(0, 10), 'b': range(1, 11)})
print('A = ')
print(A)
数据A 如下
A =
a b
0 0 1
1 1 2
2 2 3
3 3 4
4 4 5
5 5 6
6 6 7
7 7 8
8 8 9
9 9 10
我们可以看到数据A由两列组成:’a’列和’b’列,分别是0到9,1到10
B = A.loc[0::2, ] # 提取奇数行
print('B = ')
print(B)
数据B如下:
B =
a b
0 0 1
2 2 3
4 4 5
6 6 7
8 8 9
注意:数据B是通过loc函数切片筛选奇数行,且它的 行索引并不连续
3.提取部分数据C
C = A.loc[1::2, ] # 提取偶数列
print('C = ')
print(C)
数据C如下:
C =
a b
1 1 2
3 3 4
5 5 6
7 7 8
9 9 10
注意:数据C是通过loc函数切片筛选偶数行,且它的 行索引并不连续
4.将数据B中的’a’列赋值到数据C的’a’列
B['a'] = C['a']
pandas会弹出SettingWithCopyWarning警告
D:\Pyton\main.py:11: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
B['a'] = C['a']
那么B最终结果是什么呢
print('B = ')
print(B)
B =
a b
0 NaN 1
2 NaN 3
4 NaN 5
6 NaN 7
8 NaN 9
注意:数据C中’a’列并未赋值到数据B来,且原有的数据被修改为Nan
pandas无法判断切片后的是视图还是副本,即:切片后的数据,仅仅是一个视图,如果我们修改视图,不会修改原数据,但我们以上的代码对视图赋值时,pandas无法判断报出警告。(个人理解:我们赋值的时候仅仅是传入原数据C的 行索引,而非实际值,但这些索引又无法在数据B中找到,且传入的索引也没有数据B所需要的索引。故数据B中的’a’列为 NaN )
如果 行索引一致,是否可以成功赋值
D = A.loc[1::2, ] # 和数据C一致
D['a'] = C['b'] # 将数据C中'b'列赋值给D的'a'列
print('D = ')
print(D)
数据D结果如下:
D =
a b
1 2 2
3 4 4
5 6 6
7 8 8
9 10 10
虽然成功赋值,但是会有 警告
D:\Pyton\main.py:15: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
D['a'] = C['b']
该警告和前面一样一样的,说明这么赋值的方式 不对
如果接受数据中包含传入数据的行索引,也包含其他行索引,又是怎样的结果呢?
E = A.loc[1:, :]
E['a'] = C['b']
print('E = ')
print(E)
数据E如下:
E =
a b
1 2.0 2
2 NaN 3
3 4.0 4
4 NaN 5
5 6.0 6
6 NaN 7
7 8.0 8
8 NaN 9
9 10.0 10
注意:传入数据(如:数据C)和接受数据(如:数据E)的行数并不相等,但pandas 没有报错,同时也可以看到只有与数据C对应的行被赋值了,其他行被设置为 Nan,同时也会弹出 SettingWithCopyWarning警告
针对前面的分析,我们在处理类似问题时,需要利用.copy()对切片的数据进行备份,才能对数据进行赋值。如:
F = A.loc[1::2, ].copy() # 比数据D多个.copy()
F['a'] = C['b']
print('F = ')
print(F)
结果如下:
F =
a b
1 2 2
3 4 4
5 6 6
7 8 8
9 10 10
补充,那如果我们将数据A整体当作筛选数据呢
G = A.loc[:, :] # 仅比数据E多第一行
G['a'] = C['b']
print('G = ')
print(G)
print("A = \n", A)
其结果如下:
G =
a b
0 NaN 1
1 2.0 2
2 NaN 3
3 4.0 4
4 NaN 5
5 6.0 6
6 NaN 7
7 8.0 8
8 NaN 9
9 10.0 10
A =
a b
0 NaN 1
1 2.0 2
2 NaN 3
3 4.0 4
4 NaN 5
5 6.0 6
6 NaN 7
7 8.0 8
8 NaN 9
9 10.0 10
发现:数据G中仅有偶数行被修改,奇数行被设置为 Nan, 且 数据A也被修改,但是此过程中pandas 即没有报错,也没弹警告。
我们对数据进行切片时,而且后期还需要对这些数据进行修改,我们因该利用.copy()对切片后的数据进行备份。
个人理解,勿喷,有错请指正
Original: https://blog.csdn.net/qq_39362837/article/details/127462987
Author: 棠木屋
Title: Pandas_切片赋值、SettingWithCopyWarning
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/677343/
转载文章受原作者版权保护。转载请注明原作者出处!