熊猫使用 Idmax 应用错误地将混合对象列转换为浮点数



所以我的数据集中有各种列,这些列是整数和字符串的混合。尝试删除重复项,我将行中的每一列转换为字符串,获取其长度,并将该长度添加为额外的列:

import pandas as pd
import datetime
r1 = [datetime.date(2016, 7, 10), 'M']
r2 = [datetime.date(2014, 11, 26), 0]
r3 = [datetime.date(2015, 8, 13), 'M']
r4 = [datetime.date(2015, 5, 11), 'OPSTC']
r5 = [datetime.date(2014, 1, 31), 'FMS']
df = pd.DataFrame([r1, r2, r3, r4, r5], columns=['date', 'mix'])
df['date'] = pd.to_datetime(df['date'])
def f(row):
    return(row.apply(lambda x: len(str(x))).sum())
df['width'] = df.apply(f, axis=1)
df
    date        mix     width
0   2016-07-10  M       20
1   2014-11-26  0       20
2   2015-08-13  M       20
3   2015-05-11  OPSTC   24
4   2014-01-31  FMS     22
for column in df.columns:
    print(column, df[column].dtype)
date  datetime64[ns]
mix   object
width int64

这不会产生任何问题。当我对行进行分组并消除那些没有最高行总数的行时,就会出现问题:

def f(rows):
    rows.applymap(str) # Even putting this in here has no effect!
    return(rows.ix[rows['width'].idxmax()])
df = df.groupby(['date'], as_index=False).apply(f)
df = df.reset_index(drop=True)
df
    date        mix width
0   2014-01-31  NaN 22
1   2014-11-26  0.0 20
2   2015-05-11  NaN 24
3   2015-08-13  NaN 20
4   2016-07-10  NaN 20

它将混合对象列转换为浮点数。您可以按混合或日期分组以重现问题。将列转换为字符串(通过使用 .apply(str).astype(str) (不起作用。

我正在使用Python 3.5.2.final.0和Pandas 0.18.1。

这里有几个失败点

  • 无法分配给变量

    def f(rows):
        rows.applymap(str)  # this doesn't get assigned
        return rows.ix[rows['width'].idxmax()]
    
  • 不要使用ix. 不影响这里的任何事情。 但它将被弃用。

  • 超级微妙和危险的点... row.ix[rows['width'].idxmax()]返回一个pd.Series。 为什么这很重要? 目前我无法确定整个故事(我正在努力(。 但是,当你返回时,pd.Series pandas正在进行一些推断并确定'mix'应该是数字。 groupby对象的apply方法将pd.DataFrame对象传递给正在应用的函数。 您可以通过将标量rows['width'].idxmax()转换为类似数组的[rows['width'].idxmax()]来解决此问题

    def f(rows):
        return rows.loc[[rows['width'].idxmax()]] 
    print(df.groupby(['date'], as_index=False).apply(f))
               date    mix  width
    0 4 2014-01-31    FMS     22
    1 1 2014-11-26      0     20
    2 3 2015-05-11  OPSTC     24
    3 2 2015-08-13      M     20
    4 0 2016-07-10      M     20
    
  • 好的,所以dtypes再次有意义,但是您没有消除任何东西,因为您按date分组,其中所有唯一之处。 不确定你在这里想要什么,但这是一个猜测。

    df.query('width == @df.width.max()')
    # equivalently
    # df[df.width == df.width.max()]  
            date    mix  width
    3 2015-05-11  OPSTC     24
    

最新更新