给出一个warning的提示如下:

main.py:42: 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: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
d1[0] = 999

其中main.py:42是发生这个warning的代码行,d1[0]=999是warning发生的具体代码,同时给出了建议的替代方式和官方参考文档的链接。

在这篇博客pandas的引用和复制中作者总结了7种引用和复制的场景,个人感觉没有从本质上解决问题,但是提供了一个很好的研究范例。假设改变数据产生函数的定义,各种情景又会不同,例如给出一种数据产生函数的定义:

def data_gen():
    data = {'a':[1,2,3],'b':[5,6,7],'c':[6,6,6]}
    df = pd.DataFrame(data)
    return df

此外,在交互式命令行下和python脚本下的执行也会不同。例如,代码41行在交互式模式下运行会给出警告,但是如果直接执行python脚本则没有警告。

[补充: 天池-蚂蚁金服:商场中精确定位用户所在店铺 实验对比]

给定Pandas元素赋值,有三种方式如下:

  • df.set_value(行名称,列名称,新值):

  • df.loc[行名称,列名称] = 新值

  • df.iloc[行标][列标] = 新值

在脚本环境中,方式一和方式二能够成功赋值,交互式环境下三种方式都OK!(为什么第三种方式在脚本环境下不能赋值?)

处理483931个object类型(字符串类型),方式一用时330s,方式二用时远远超过330s(为啥没有具体结果,因为没有耐心等到结果出现,逃)。

[补充:Pandas大规模值替换的一个例子(200w样本,1s左右)]

df.col_name = df.col_name.map({value0: new_value0, value1: new_value1})

在IJCAI2017比赛中的特征处理时的一行代码:

m2Data.loc[:,'dayofweek'] = map(lambda x:x.dayofweek,m2Data['time_stamp'])

[补充:现在有一个pandas的Series和一个python的list,想让Series按指定的list进行排序,如何实现?]

reorder_categories和set_categories,可以参考这篇文章

看到更简单的代码:

s = pd.Series([4.5, 2.7, 8.9, -0.4], index = ['d', 'b', 'a', 'c'])

s.reindex(['a', 'b', 'c', 'd', 'e'])

关于引用和复制的问题,可能会造成很难发现的错误。也就是数据是”正确”的,运行不出错,但是和期望结果会相差很多,很难发现。一种可能的方式是采用类似”梯度校验”的方式,进行数据验证,但是难免繁琐,所以总结一句,不能轻易放过代码的任何一个warning,因为任何warning都是潜在错误的表现。