title: 学习 pandas [02]: 二进制操作 slug: er-jin-zhi-cao-zuo date: 2021-1-23 tags:

  • Pandas
  • Jupyter
  • python category: 数据分析 link: description: type: text

二进制操作

Pandas数据结构之间执行二进制操作,要注意下列两个关键点:

  • DataFrame与Series之间的广播机制;
  • 计算中的缺失值处理。

加、减、乘、除、取模

DataFrame支持以下运算操作中对Series进行广播:

  • add():加
  • sub():减
  • mul():乘
  • div():除
  • radd()
  • rsub()

在以上方法使用中,通过axis参数,指定沿indexcolumns广播。

sub()举例。

df.sub(other, axis='columns', level=None, fill_value=None)

  • other:被减去的常数、序列、DataFrame或Series。如果是Series,则会按axis参数进行广播,也就是df的每行(或列)都执行减去Series。
  • axis:可选值为columns或index,指定沿行或列广播。
  • level:可选值为整数或标签,对于有多层及索引的df,指定Series对齐多层索引df的某一层级。
  • fill_value:指定一个值代替df和other中的NaN。只对other为DataFrame时起作用。如果在df和other的相同位置都是NaN,则运算结果也是NaN。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import numpy as np
import pandas as pd

df = pd.DataFrame({
    'one': pd.Series(np.random.randn(3), index=['a', 'b', 'c']),
    'two': pd.Series(np.random.randn(4), index=['a', 'b', 'c', 'd']),
    'three': pd.Series(np.random.randn(3), index=['b', 'c', 'd'])
})

df
onetwothree
a-0.0626891.465328NaN
b-2.187806-0.2999470.670050
c-0.7951050.803948-0.016265
dNaN-2.9758000.280831
1
2
3
row = df.iloc[1]
df1 = df.sub(row, axis='columns')
df1
onetwothree
a2.1251181.765275NaN
b0.0000000.0000000.000000
c1.3927011.103896-0.686316
dNaN-2.675852-0.389220
1
2
3
4
5
6
df2 = pd.DataFrame({
    'one': pd.Series(np.random.randn(3), index=['a', 'b', 'c']),
    'two': pd.Series(np.random.randn(4), index=['a', 'b', 'c', 'd']),
    'three': pd.Series(np.random.randn(4), index=['a', 'b', 'c', 'd'])
})
df2
onetwothree
a-0.9308140.543193-3.300306
b-0.7568361.236183-0.116324
c1.2709640.9583560.802346
dNaN0.818930-0.072648
1
2
df3 = df.sub(df2, fill_value=10)
df3
onetwothree
a0.8681260.92213413.300306
b-1.430970-1.5361300.786375
c-2.066069-0.154408-0.818611
dNaN-3.7947300.353479

比较操作

Series与DataFrame支持以下比较操作:

  • eq():等于
  • ne():不等于
  • lt():小于
  • gt():大于
  • le():小于或等于
  • ge():大于或等于
  • equals():直接比较两个Series或两个DataFrame是否相等。此方法将NaN与NaN比较结果视为相等。 用法与加减乘除类似。以lt()举例。

df.lt(other, axis='columns', level=None)

  • other:被比较的常数、序列、DataFrame或Series。如果是Series,则会按axis参数进行广播,也就是df的每行(或列)都执行减去Series。
  • axis:可选值为columns或index,指定沿行或列广播。
  • level:可选值为整数或标签,对于有多层及索引的df,指定Series对齐多层索引df的某一层级。

equals()返回值为布尔值,以上其他方法返回值为与df构造相同的元素为布尔值的DataFrame或Series。

1
df.lt(df2)
onetwothree
aFalseFalseFalse
bTrueTrueFalse
cTrueTrueTrue
dFalseTrueFalse
1
df.lt(row, axis='columns')
onetwothree
aFalseFalseFalse
bFalseFalseFalse
cFalseFalseTrue
dFalseTrueTrue
1
df.lt(0)
onetwothree
aTrueFalseFalse
bTrueTrueFalse
cTrueFalseTrue
dFalseTrueFalse

直接用df == df比较,返回False,因为df中含有NaN,两个NaN值的比较结果为不等。因此需使用equals()方法。

1
(df == df).all().all()
False
1
df.equals(df)
True

布尔简化

可以把数据汇总简化成单个布尔值。

  • empty:DataFrame或Series的属性,非方法,验证是否为空。
  • any():任意一个元素为真则为真。每使用一次则返回值减少一个维度。
  • all():全部元素为真则为真。每使用一次则返回值减少一个维度。
  • bool():验证单元素pandas对象的布尔值。
1
df.empty
False
1
pd.Series([True]).bool()
True

any()all()用法类似。以any()举例。

df.any(axis=0, bool_only=None, skipna=True, level=None)

  • axis:取值为0/‘index’、1/‘columns’、None,默认0,指定哪个维度被减少,如果取值None,则减去所有维度返回常数。
  • bool_only:取值为布尔值,默认None。是否只利用序列中的布尔值进行判断,取None后会使用任何值。对Series无效。
  • skipna:取值为布尔值,是否跳过NA/null值。默认值为True,则将整行/列都是NA的当作空行/列,返回False。反之不当作空行/列,返回True。
  • level:可选值为整数或标签,对于有多层及索引的df,指定某一层级。
1
df.lt(0).any()
one      True
two      True
three    True
dtype: bool
1
df.lt(0).all()
one      False
two      False
three    False
dtype: bool
1
df.lt(0).any().all()
True

合并重叠数据

df5.combine_first(df6)

将df5中的NaN值以及空行/列,填充df6中对应位置的值。

1
2
3
4
5
6
7
8
df5 = pd.DataFrame({'A': [1., np.nan, 3., 5., np.nan],
                    'B': [np.nan, 2., 3., np.nan, 6.]})

df6 = pd.DataFrame({'A': [5., 2., 4., np.nan, 3., 7.],
                    'B': [np.nan, np.nan, 3., 4., 6., 8.],
                    'C': [2., 3., 9., 10., 11., 12.]})

df5
AB
01.0NaN
1NaN2.0
23.03.0
35.0NaN
4NaN6.0
1
df6
ABC
05.0NaN2.0
12.0NaN3.0
24.03.09.0
3NaN4.010.0
43.06.011.0
57.08.012.0
1
df5.combine_first(df6)
ABC
01.0NaN2.0
12.02.03.0
23.03.09.0
35.04.010.0
43.06.011.0
57.08.012.0