划分两个pandas DataFrames并保留非数字列

时间:2018-03-21 17:15:02

标签: python pandas

我有两个包含数字和非数字值的pandas DataFrame。我想将一个除以另一个,但保留非数字列。这是一个MWE:

<div class="container">
  <input type="text" id="no1" name="no1">
  <input type="text" id="no2" name="no2">
</div>

<div id="message"></div>

尝试做:

a = pd.DataFrame(
    [
        ['group1', 1., 2.],
        ['group1', 3., 4.],
        ['group1', 5., 6.]
    ], 
    columns=['Group', 'A', 'B']
)

b = pd.DataFrame(
    [
        ['group1', 7., 8.],
        ['group1', 9., 10.],
        ['group1', 11., 12.]
    ],
    columns=['Group', 'A', 'B']
)

结果:

  

b.div(a)

所以为了解决这个问题,我已经完成了:

TypeError: unsupported operand type(s) for /: 'str' and 'str'

哪个是正确的,但我还想保留专栏result = b.drop(["Group"], axis=1).div(a.drop(["Group"], axis=1)) print(result) # A B #0 7.0 4.0 #1 3.0 2.5 #2 2.2 2.0

获得我想要的输出的一种方法是:

"Group"

但我真正的DataFrames有许多非数字列。是否有更清洁/更快/更有效的方法来告诉大熊猫只划分数字列?

3 个答案:

答案 0 :(得分:2)

您可以使用np.divide,将掩码传递给where参数。

np.divide(b, a, where=a.dtypes.ne(object))

假设DataFrame中的非数字列相同,请使用combine_first / fillna将其取回:

np.divide(b, a, where=a.dtypes.ne(object)).combine_first(a)


    Group    A    B
0  group1  7.0  4.0
1  group1  3.0  2.5
2  group1  2.2  2.0

答案 1 :(得分:1)

与@cᴏʟᴅsᴘᴇᴇᴅ的答案类似,但您可以.select_dtypes()留在熊猫队中。这将尝试在任何非对象dtypes上进行索引对齐除法。

>>> b.select_dtypes(exclude='object').div(
...     a.select_dtypes(exclude='object')).combine_first(a)
...     
     A    B   Group
0  7.0  4.0  group1
1  3.0  2.5  group1
2  2.2  2.0  group1

保留列排序:

>>> desired_output = b.select_dtypes(exclude='object')\
...     .div(a.select_dtypes(exclude='object'))\
...     .combine_first(a)[a.columns]

>>> desired_output
    Group    A    B
0  group1  7.0  4.0
1  group1  3.0  2.5
2  group1  2.2  2.0

答案 2 :(得分:1)

也许set_index()

b.set_index('Group').div(a.set_index('Group'),level=[0]).reset_index()
Out[579]: 
    Group    A    B
0  group1  7.0  4.0
1  group1  3.0  2.5
2  group1  2.2  2.0

适用于更多字符串类型列

pd.concat([b,a]).groupby(level=0).agg(lambda x : x.iloc[0]/x.iloc[1] if x.dtype=='int64' else x.head(1))
Out[584]: 
    Group     A     B
0  group1   7.0   8.0
1  group1   9.0  10.0
2  group1  11.0  12.0