如何在包含混合数据类型的Pandas DataFrame中舍入值以进行进一步的数据比较?

时间:2015-05-15 11:15:13

标签: python numpy pandas

我有一个数据帧df_left:

  IDX1 IDX2 IDX3     IDX4 ValueType Value
0    A   A1    Q  1983 Q4         W    10.123
1    A   A1    Q  1983 Q4         X     A
2    A   A1    Q  1983 Q4         Y     F
3    A   A1    Q  1983 Q4         Z   NaN
4    A   A1    Q  1984 Q1         W   110.456
...

从上一篇文章创建:

Background information

AND dataframe df_right:

  IDX1 IDX2 IDX3     IDX4 ValueType Value
0    A   A1    Q  1983 Q4         W    10
1    A   A1    Q  1983 Q4         X     A
2    A   A1    Q  1983 Q4         Y     F
3    A   A1    Q  1983 Q4         Z   NaN
4    A   A1    Q  1984 Q1         W   110

我比较并协调以下数据和文本的数据:

df_compare = pd.merge(df_Left, df_Right, how ='outer', on = ['IDX1', 'IDX2', 'IDX3', 'IDX4', 'ValueType'])
df_compare.columns = ['IDX1', 'IDX2', 'IDX3', 'IDX4', 'ValueType', 'From', 'To']
df_compare = df_compare[df_compare.From!=df_compare.To]

虽然结果与预期一致,但在比较之前,我希望将值数据中的数据四舍五入。

我试过了:

df.apply(np.round)

还有:

df.round(decimals=0, out=None)

但两者都如预期的那样发生错误:

AttributeError: ("'str' object has no attribute 'rint'", u'occurred at index Code')

2 个答案:

答案 0 :(得分:3)

这是一个相当通用的解决方案,您可以应用于多个列。 ' To'列不需要舍入,我只是将它包含在两列的通用性而不是一列中:

Text

这是最安全的方式,因为它不会让你意外地消除非数字值,但如果你有真正的混合类型,你可以这样做:

df

  IDX1 IDX2  IDX3 IDX4 ValueType     From   To
0   A1    Q  1983   Q4         W   10.123   10
3   A1    Q  1983   Q4         Z      NaN  NaN
4   A1    Q  1984   Q1         W  110.456  110

In [399]: df[['From','To']].astype(float).apply(np.round)

   From   To
0    10   10
3   NaN  NaN
4   110  110

但是因为这会将任何非数字值转换为NaN,所以在覆盖任何内容之前,请确保它是您想要的。

答案 1 :(得分:0)

仅对浮点数进行舍入的自定义方法可以解决舍入混合dtype列的问题


In [238]: def round_float(s):
    '''1. if s is float, round it to 0 decimals
       2. else return s as is
    '''
    import re
    m = re.match("(\d+\.\d+)",s.__str__())
    try:
        r = round(float(m.groups(0)[0]),0)
    except:
        r = s
    return r

In [239]: s = u'''  IDX1 IDX2 IDX3     IDX4 ValueType Value
0    A   A1    Q  1983 Q4         W    10.23
1    A   A1    Q  1983 Q4         X     A
2    A   A1    Q  1983 Q4         Y     F
3    A   A1    Q  1983 Q4         Z   NaN
4    A   A1    Q  1984 Q1         W   110.15'''

In [240]: df1 = pd.read_csv(StringIO(s), delimiter="\s+")

In [241]: df1["Value2"] = df1.Value.apply(round_float)

In [242]: df1
Out[242]:
    IDX1 IDX2  IDX3 IDX4 ValueType   Value Value2
0 A   A1    Q  1983   Q4         W   10.23     10
1 A   A1    Q  1983   Q4         X       A      A
2 A   A1    Q  1983   Q4         Y       F      F
3 A   A1    Q  1983   Q4         Z     NaN    NaN
4 A   A1    Q  1984   Q1         W  110.15    110