2017-05-13 52 views
1

使用Pandas read_excel函数时,我发现了一些奇怪的行为。我有一个电子表格,看起来像一个人为的例子:熊猫read_excel na_values和转换器之间的干扰错误?

Name age weight 
Bob  35 70 
Alice 15 ... 
Sam  ... 65 
Susan 92 63 
Harold 42 ... 

缺失值被表示为“......”我想他们理解为NaN的。我也想将权重转换为克。我的第一个尝试是:

df=pd.read_excel('test.xls',na_values='...',converters={'weight':lambda y:y*1000}) 

不幸的是,这第一个适用的转换器功能,让苏珊和哈罗德的缺失权重变得不是三个点,但3000点,这不符合给定“na_value”项,因此不变成了NaN。这是非常意外的。

是否有理由认为这是该功能的最佳行为?

我在执行它时做了一些明显的错误吗?

什么是获得我想要的行为的最佳方式?

回答

2

converters在应用na_values之前运行,这就是您看到此行为的原因。
在转换器只需添加一个条件,以赶上...实例中weights - 如添加手卷na_values

df = pd.read_excel("test.xls", 
        na_values="...", 
        converters={"weight":lambda w: w*1000 if isinstance(w, int) else None}) 

print(df) 

    Name age weight 
0  Bob 35.0 70000.0 
1 Alice 15.0  NaN 
2  Sam NaN 65000.0 
3 Susan 92.0 63000.0 
4 Harold 42.0  NaN 

保持实际na_values参数,以确保在age领域...值也被转换。

+0

谢谢你,安德鲁。我会稍微调整一下你的解决方案:'如果isinstance(w,int)else x})'将会导致convereter留下一个非int值_alone_,我认为更好。最终,由于其他奇怪的行为,我放弃了这种方法。很难给出一个简单的例子,但在我的实际数据中,使用像这样的lambda函数改变了结果列的dtype,并且破坏了一些Numpy功能。稍后调用DataFrame.corr()会忽略出于某种原因而受到lambda表达式限制的列。奇。再次感谢! –

0

我会做这种方式:

df = pd.read_excel('test.xls', na_values='...') \ 
     .eval("weight = weight * 1000", inplace=False) 
0

我不认为你需要使用转换器参数在这种情况下。 在read_excel之后执行该操作。我甚至相信有更好的表现。

像这样:

df=pd.read_excel('test.xls', .... 
df['weight'] *= 1000