Pandas将列拆分为两个并获取名称后缀错误

时间:2015-05-26 17:53:28

标签: python pandas

我有一个pandas数据帧,一列是温度(人类),但是值是混合的,摄氏和华氏,我想把这个列分成两列(保留原始列)

#C Temp will be added to the end of df 
df = df.join(df.Temp.apply(lambda x: np.nan if x > 43 else x))

#F Temp will be added to the end of df 
df = df.join(df.Temp.apply(lambda x: np.nan if x < 43 else x))

我认为df.Temp.apply(lambda x: np.nan if x < 43 else x)将返回一系列将加入df的结尾,但我收到此错误

ValueError: columns overlap but no suffix specified: Index([u'Temp'], dtype='object')

2 个答案:

答案 0 :(得分:2)

问题在于,对name的调用中实时计算Series的隐式join属性也是'Temp',因为它是&#39 ; sa来自该列的派生计算。由于'Temp'已存在于DataFrame中,因此它会引发异常,以表明它不知道您希望使用哪种名称更改(通过后缀)来防止名称重叠。

您可以向rsuffix提供一个join参数,该参数会将一个给定字符串附加到该名称,该列来自该联接的 right 操作数(在此case,函数调用中的一个)。例如:

df = df.join(df.Temp.apply(lambda x: np.nan if x > 43 else x),
             rsuffix='_Celsius')

在修改后的输出DataFrame中获取名为"Temp_Celsius"的列。还可以选择使用lsuffix提供将附加到 left 操作数的字符串,如果您希望更改该列名称(或者您可以提供)如果您不希望任何列保留原始名称,则两者

但请注意,在使用on时,您总是忽略任何join参数(加入条件) - 这意味着您默认为&#34;加入&#34;按指数。实际上,你想要的只是简单地写一个从旧列派生的新列,这使你有机会声明名称,例如:

df['Celsius'] = df.Temp.apply(lambda x: np.nan if x > 43 else x)

这是更可取的,因为它更清楚地表达了您的意图,不是为了加入而是为了创建一个列。此外,由于默认的连接方法是'left',如果您碰巧有重复的索引,您可能最终会为左侧索引中的每个副本多次连接,并且因为该索引与右侧相同-hand index(因此也会有重复)这可能意味着你会默默地错误地为每个连接引入更多重复项。

您也可以选择使用map代替apply,因为在访问专栏时,您将使用系列对象。

答案 1 :(得分:0)

我想补充一点,您可以使用where方法更有效,更优雅地计算所需的系列:

df['Celsius'] = df.Temp.where(df.Temp > 43)

这是一个矢量化解决方案,这意味着内部循环是用C实现的。.apply应该避免使用python循环并且速度要慢得多。此外,应尽可能避免使用lambda函数,因为它们也会使您在多次迭代中减慢速度。熊猫作为这些问题的内置功能的负载。