8.2 Combining and Merging Datasets(合并数据集)
pandas
里有几种方法可以合并数据:
pandas.merge
按一个或多个key
把DataFrame
中的行连接起来。这个和SQL
或其他一些关系型数据库中的join
操作相似。pandas.concat
在一个axis
(轴)上,串联或堆叠(stack
)多个对象。combine_first
实例方法(instance method
)能拼接相互之间有重复的数据,并用一个对象里的值填满缺失值
这里每一个都会给出一些例子。这些用法贯穿这本书。
1 Database-Style DataFrame Joins(数据库风格的DataFrame Joins)
Merge
或join
操作,能通过一个或多个key
,把不同的数据集的行连接在一起。这种操作主要集中于关系型数据库。pandas
中的merge
函数是这种操作的主要切入点:
python">word">import pandas word">as pd
word">import numpy word">as np
python">df1 = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
'data1': range(7)})
df1
| data1 | key |
---|
0 | 0 | b |
---|
1 | 1 | b |
---|
2 | 2 | a |
---|
3 | 3 | c |
---|
4 | 4 | a |
---|
5 | 5 | a |
---|
6 | 6 | b |
---|
python">df2 = pd.DataFrame({'key': ['a', 'b', 'd'],
'data2': range(3)})
df2
这个例子是many-to-one join
(多个变为一个的结合);在df1
中有标签为a
和b
的行,而df2
中的key
列,每一行只有对应的一个值。调用merge
我们可以得到:
python">pd.merge(df1, df2)
| data1 | key | data2 |
---|
0 | 0 | b | 1 |
---|
1 | 1 | b | 1 |
---|
2 | 6 | b | 1 |
---|
3 | 2 | a | 0 |
---|
4 | 4 | a | 0 |
---|
5 | 5 | a | 0 |
---|
这里我们并没有指定按哪一列来合并。如果我们没有指定,merge
会用两个对象中都存在的列名作为key
(键)。当然,最好还是清楚指定比较好:
python">pd.merge(df1, df2, on='key')
| data1 | key | data2 |
---|
0 | 0 | b | 1 |
---|
1 | 1 | b | 1 |
---|
2 | 6 | b | 1 |
---|
3 | 2 | a | 0 |
---|
4 | 4 | a | 0 |
---|
5 | 5 | a | 0 |
---|
如果每一个对象中的列名不一会,我们可以分别指定:
python">df3 = pd.DataFrame({'lkey': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
'data1': range(7)})
df4 = pd.DataFrame({'rkey': ['a', 'b', 'd'],
'data2': range(3)})
python">pd.merge(df3, df4, left_on='lkey', right_on='rkey')
| data1 | lkey | data2 | rkey |
---|
0 | 0 | b | 1 | b |
---|
1 | 1 | b | 1 | b |
---|
2 | 6 | b | 1 | b |
---|
3 | 2 | a | 0 | a |
---|
4 | 4 | a | 0 | a |
---|
5 | 5 | a | 0 | a |
---|
我们可能注意到,在结果中并没有c
和d
。因为merge
默认是inner join
(内联结),结果中的key
是交集的结果,或者在两个表格中都有的集合。其他一些可选项,比如left, right, outer。outer join
(外联结)取key
的合集,其实就是left join
和right join
同时应用的效果:
python">pd.merge(df1, df2, how='outer')
| data1 | key | data2 |
---|
0 | 0.0 | b | 1.0 |
---|
1 | 1.0 | b | 1.0 |
---|
2 | 6.0 | b | 1.0 |
---|
3 | 2.0 | a | 0.0 |
---|
4 | 4.0 | a | 0.0 |
---|
5 | 5.0 | a | 0.0 |
---|
6 | 3.0 | c | NaN |
---|
7 | NaN | d | 2.0 |
---|
many-to-many
(多对多)结合也被定义好了,不过可能不是那么直观。这里有一个例子:
python">df1 = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'b'],
'data1': range(6)})
df1
| data1 | key |
---|
0 | 0 | b |
---|
1 | 1 | b |
---|
2 | 2 | a |
---|
3 | 3 | c |
---|
4 | 4 | a |
---|
5 | 5 | b |
---|
python">df2 = pd.DataFrame({'key': ['a', 'b', 'a', 'b', 'd'],
'data2': range(5)})
df2
python">pd.merge(df1, df2, on='key', how='left')
| data1 | key | data2 |
---|
0 | 0 | b | 1.0 |
---|
1 | 0 | b | 3.0 |
---|
2 | 1 | b | 1.0 |
---|
3 | 1 | b | 3.0 |
---|
4 | 2 | a | 0.0 |
---|
5 | 2 | a | 2.0 |
---|
6 | 3 | c | NaN |
---|
7 | 4 | a | 0.0 |
---|
8 | 4 | a | 2.0 |
---|
9 | 5 | b | 1.0 |
---|
10 | 5 | b | 3.0 |
---|
many-to-many join
是对行进行笛卡尔集运算。(两个集合X和Y的笛卡儿积(Cartesian product
),又称直积,在集合论中表示为X × Y,是所有可能的有序对组成的集合。比如1到13是一个集合,四种花色是一个集合,二者的笛卡尔积就有52个元素)。这里在左侧的DataFrame
中有三行含b,右边的DataFrame
则有两行含b,于是结果是有六行含b。这个join
方法只会让不相同的key
值出现在最后的结果里:
python">pd.merge(df1, df2, how='inner')
| data1 | key | data2 |
---|
0 | 0 | b | 1 |
---|
1 | 0 | b | 3 |
---|
2 | 1 | b | 1 |
---|
3 | 1 | b | 3 |
---|
4 | 5 | b | 1 |
---|
5 | 5 | b | 3 |
---|
6 | 2 | a | 0 |
---|
7 | 2 | a | 2 |
---|
8 | 4 | a | 0 |
---|
9 | 4 | a | 2 |
---|
用多个key
来联结的话,用一个含有多个列名的list
来指定:
python">left = pd.DataFrame({'key1': ['foo', 'foo', 'bar'],
'key2': ['one', 'two', 'one'],
'lval': [1, 2, 3]})
right = pd.DataFrame({'key1': ['foo', 'foo', 'bar', 'bar'],
'key2': ['one', 'one', 'one', 'two'],
'rval': [4, 5, 6, 7]})
python">pd.merge(left, right, on=['key1', 'key2'], how='outer')
| key1 | key2 | lval | rval |
---|
0 | foo | one | 1.0 | 4.0 |
---|
1 | foo | one | 1.0 | 5.0 |
---|
2 | foo | two | 2.0 | NaN |
---|
3 | bar | one | 3.0 | 6.0 |
---|
4 | bar | two | NaN | 7.0 |
---|
哪一种key
组合会出现在结果里取决于merge
方法的选择,可以把多个key
当做一个tuple
组成的单一key
(尽管实际上并不是这样)。
注意:当我们讲列和列进行联结时,DataFrame
中的index
对象会被丢弃。
最后一个问题是在做merge
操作的时候,如何处理重叠的列名。当我们想要手动去解决重叠问题时(参考重命名axis labels
的部分),merge
有一个suffixes
选项,能让我们指定字符串,添加重叠的列名到左、右DataFrame
:
python">pd.merge(left, right, on='key1')
| key1 | key2_x | lval | key2_y | rval |
---|
0 | foo | one | 1 | one | 4 |
---|
1 | foo | one | 1 | one | 5 |
---|
2 | foo | two | 2 | one | 4 |
---|
3 | foo | two | 2 | one | 5 |
---|
4 | bar | one | 3 | one | 6 |
---|
5 | bar | one | 3 | two | 7 |
---|
python">pd.merge(left, right, on='key1', suffixes=('_left', '_right'))
| key1 | key2_left | lval | key2_right | rval |
---|
0 | foo | one | 1 | one | 4 |
---|
1 | foo | one | 1 | one | 5 |
---|
2 | foo | two | 2 | one | 4 |
---|
3 | foo | two | 2 | one | 5 |
---|
4 | bar | one | 3 | one | 6 |
---|
5 | bar | one | 3 | two | 7 |
---|
2 Merging on Index(在index上做合并)
在一些情况下,用于合并的key
(键),可能是DataFrame
中的index
。这种情况下,可以使用left_index=True
或 right_index=True
来指明,哪一个index
被用来作为合并键:
python">left1 = pd.DataFrame({'key': ['a', 'b', 'a', 'a', 'b', 'c'],
'value': range(6)})
left1
| key | value |
---|
0 | a | 0 |
---|
1 | b | 1 |
---|
2 | a | 2 |
---|
3 | a | 3 |
---|
4 | b | 4 |
---|
5 | c | 5 |
---|
python">right1 = pd.DataFrame({'group_val': [3.5, 7]}, index=['a', 'b'])
right1
python">pd.merge(left1, right1, left_on='key', right_index=True)
| key | value | group_val |
---|
0 | a | 0 | 3.5 |
---|
2 | a | 2 | 3.5 |
---|
3 | a | 3 | 3.5 |
---|
1 | b | 1 | 7.0 |
---|
4 | b | 4 | 7.0 |
---|
merge
的默认方法是用key
的交集,我们也可以设定用合集,即outer join
:
python">pd.merge(left1, right1, left_on='key', right_index=True, how='outer')
| key | value | group_val |
---|
0 | a | 0 | 3.5 |
---|
2 | a | 2 | 3.5 |
---|
3 | a | 3 | 3.5 |
---|
1 | b | 1 | 7.0 |
---|
4 | b | 4 | 7.0 |
---|
5 | c | 5 | NaN |
---|
对于那些有多层级索引的数据,就更复杂了。index
上的merge
默认会是multiple-key merge
(复数键合并):
python">lefth = pd.DataFrame({'key1': ['Ohio', 'Ohio', 'Ohio',
'Nevada', 'Nevada'],
'key2': [2000, 2001, 2002, 2001, 2002],
'data': np.arange(5.)})
lefth
| data | key1 | key2 |
---|
0 | 0.0 | Ohio | 2000 |
---|
1 | 1.0 | Ohio | 2001 |
---|
2 | 2.0 | Ohio | 2002 |
---|
3 | 3.0 | Nevada | 2001 |
---|
4 | 4.0 | Nevada | 2002 |
---|
python">righth = pd.DataFrame(np.arange(12).reshape((6, 2)),
index=[['Nevada', 'Nevada', 'Ohio', 'Ohio',
'Ohio', 'Ohio'],
[2001, 2000, 2000, 2000, 2001, 2002]],
columns=['event1', 'event2'])
righth
| | event1 | event2 |
---|
Nevada | 2001 | 0 | 1 |
---|
2000 | 2 | 3 |
---|
Ohio | 2000 | 4 | 5 |
---|
2000 | 6 | 7 |
---|
2001 | 8 | 9 |
---|
2002 | 10 | 11 |
---|
在这个例子里,我们必须指明将多列合并作为一个list
(注意处理重复index
的方法是令how='outer'
):
python">pd.merge(lefth, righth, left_on=['key1', 'key2'],
right_index=True)
| data | key1 | key2 | event1 | event2 |
---|
0 | 0.0 | Ohio | 2000 | 4 | 5 |
---|
0 | 0.0 | Ohio | 2000 | 6 | 7 |
---|
1 | 1.0 | Ohio | 2001 | 8 | 9 |
---|
2 | 2.0 | Ohio | 2002 | 10 | 11 |
---|
3 | 3.0 | Nevada | 2001 | 0 | 1 |
---|
python">pd.merge(lefth, righth, left_on=['key1', 'key2'],
right_index=True, how='outer')
| data | key1 | key2 | event1 | event2 |
---|
0 | 0.0 | Ohio | 2000.0 | 4.0 | 5.0 |
---|
0 | 0.0 | Ohio | 2000.0 | 6.0 | 7.0 |
---|
1 | 1.0 | Ohio | 2001.0 | 8.0 | 9.0 |
---|
2 | 2.0 | Ohio | 2002.0 | 10.0 | 11.0 |
---|
3 | 3.0 | Nevada | 2001.0 | 0.0 | 1.0 |
---|
4 | 4.0 | Nevada | 2002.0 | NaN | NaN |
---|
4 | NaN | Nevada | 2000.0 | 2.0 | 3.0 |
---|
同时使用两个对象里的index
来合并也是可能的:
python">left2 = pd.DataFrame([[1., 2.], [3., 4.], [5., 6.]],
index=['a', 'c', 'e'],
columns=['Ohio', 'Nevada'])
left2
| Ohio | Nevada |
---|
a | 1.0 | 2.0 |
---|
c | 3.0 | 4.0 |
---|
e | 5.0 | 6.0 |
---|
python">right2 = pd.DataFrame([[7., 8.], [9., 10.], [11., 12.], [13, 14]],
index=['b', 'c', 'd', 'e'],
columns=['Missouri', 'Alabama'])
right2
| Missouri | Alabama |
---|
b | 7.0 | 8.0 |
---|
c | 9.0 | 10.0 |
---|
d | 11.0 | 12.0 |
---|
e | 13.0 | 14.0 |
---|
python">pd.merge(left2, right2, how='outer', left_index=True, right_index=True)
| Ohio | Nevada | Missouri | Alabama |
---|
a | 1.0 | 2.0 | NaN | NaN |
---|
b | NaN | NaN | 7.0 | 8.0 |
---|
c | 3.0 | 4.0 | 9.0 | 10.0 |
---|
d | NaN | NaN | 11.0 | 12.0 |
---|
e | 5.0 | 6.0 | 13.0 | 14.0 |
---|
DataFrame
有一个很便利的join
实例,可以直接用index
来合并。这个也可以用于与其他DataFrame
进行合并,要有一样的index
但不能由重叠的列:
python">left2.join(right2, how='outer')
| Ohio | Nevada | Missouri | Alabama |
---|
a | 1.0 | 2.0 | NaN | NaN |
---|
b | NaN | NaN | 7.0 | 8.0 |
---|
c | 3.0 | 4.0 | 9.0 | 10.0 |
---|
d | NaN | NaN | 11.0 | 12.0 |
---|
e | 5.0 | 6.0 | 13.0 | 14.0 |
---|
由于一些历史原因,在早期的pandas
版本中,DataFrame
的join
方法是在结合键上做left join
(左联结),这样会保留左侧Dataframe
的行索引。这也支持把传入的dataframe
的index
与被调用的DataFrame
的column
联结在一起:
python">left1.join(right1, on='key')
| key | value | group_val |
---|
0 | a | 0 | 3.5 |
---|
1 | b | 1 | 7.0 |
---|
2 | a | 2 | 3.5 |
---|
3 | a | 3 | 3.5 |
---|
4 | b | 4 | 7.0 |
---|
5 | c | 5 | NaN |
---|
最后,对于简单的index-on-index
合并,可以直接给join
传入一个DataFrame
。(作为备选,也可以使用最普遍的concat
函数,这个在下一节会做介绍):
python">another = pd.DataFrame([[7., 8.], [9., 10.], [11., 12.], [16., 17.]],
index=['a', 'c', 'e', 'f'],
columns=['New York', 'Oregon'])
another
| New York | Oregon |
---|
a | 7.0 | 8.0 |
---|
c | 9.0 | 10.0 |
---|
e | 11.0 | 12.0 |
---|
f | 16.0 | 17.0 |
---|
python">left2.join([right2, another])
| Ohio | Nevada | Missouri | Alabama | New York | Oregon |
---|
a | 1.0 | 2.0 | NaN | NaN | 7.0 | 8.0 |
---|
c | 3.0 | 4.0 | 9.0 | 10.0 | 9.0 | 10.0 |
---|
e | 5.0 | 6.0 | 13.0 | 14.0 | 11.0 | 12.0 |
---|
python">left2.join([right2, another], how='outer')
| Ohio | Nevada | Missouri | Alabama | New York | Oregon |
---|
a | 1.0 | 2.0 | NaN | NaN | 7.0 | 8.0 |
---|
b | NaN | NaN | 7.0 | 8.0 | NaN | NaN |
---|
c | 3.0 | 4.0 | 9.0 | 10.0 | 9.0 | 10.0 |
---|
d | NaN | NaN | 11.0 | 12.0 | NaN | NaN |
---|
e | 5.0 | 6.0 | 13.0 | 14.0 | 11.0 | 12.0 |
---|
f | NaN | NaN | NaN | NaN | 16.0 | 17.0 |
---|
2 Concatenating Along an Axis(沿着轴连接)
另一种结合方式被称为可互换的,比如concatenation, binding, or stacking
(连接,绑定,堆叠)。Numpy
中的concatenate
函数可以作用于numpy
数组:
python">arr = np.arange(12.).reshape((3, 4))
arr
array([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.]])
python">np.concatenate([arr, arr], axis=1)
array([[ 0., 1., 2., 3., 0., 1., 2., 3.],
[ 4., 5., 6., 7., 4., 5., 6., 7.],
[ 8., 9., 10., 11., 8., 9., 10., 11.]])
而在pandas
的对象中,比如Series
和DataFrame,labeled axes
(便签化的轴)能让我们做更泛化的数组连接操作。不过我们可能会有下面一些疑问:
-
如果一个对象在其他轴上的index
不同,我们应不应该在这些轴上把不同的元素连接起来,或者只用交集?
-
经过连接操作后,连接的部分在输出对象里应不应该是可被识别的?
-
concatenation axis
(连接轴)含有的数据需要被保留吗?在很多情况下,DataFrame
中一些用整数做的label
(标签)其实最好在连接后被删除。
pandas
中的concat
函数能解决上面这些问题。这里会给出几个例子来说明。假设我们有三个Series
,他们指明没有index overlap
(索引重叠):
python">s1 = pd.Series([0, 1], index=['a', 'b'])
s2 = pd.Series([2, 3, 4], index=['c', 'd', 'e'])
s3 = pd.Series([5, 6], index=['f', 'g'])
调用concat
,把上面的series
放在一个list
里,结果会把值和索引都整合在一起:
python">pd.concat([s1, s2, s3])
a 0
b 1
c 2
d 3
e 4
f 5
g 6
dtype: int64
默认情况下,concat
中axis=0
,结果会得到一个新的而series
。如果令axis=1
, 结果会变成一个DataFrame
(axis=1
是列):
python">pd.concat([s1, s2, s3], axis=1)
| 0 | 1 | 2 |
---|
a | 0.0 | NaN | NaN |
---|
b | 1.0 | NaN | NaN |
---|
c | NaN | 2.0 | NaN |
---|
d | NaN | 3.0 | NaN |
---|
e | NaN | 4.0 | NaN |
---|
f | NaN | NaN | 5.0 |
---|
g | NaN | NaN | 6.0 |
---|
这种情况下,不会与其他轴产生重叠,效果与join
中的outer join
一样。你也可以通过设定join='inner'
来使用交集:
python">s4 = pd.concat([s1, s3])
s4
a 0
b 1
f 5
g 6
dtype: int64
python">pd.concat([s1, s4], axis=1)
python">pd.concat([s1, s4], axis=1, join='inner')
因为join='inner'
,所以f和g标签消失了。
你也可以在join_axes
中指定使用哪些轴:
python">pd.concat([s1, s4], axis=1, join_axes=[['a', 'c', 'b', 'e']])
| 0 | 1 |
---|
a | 0.0 | 0.0 |
---|
c | NaN | NaN |
---|
b | 1.0 | 1.0 |
---|
e | NaN | NaN |
---|
一个潜在的问题是连接的部分在结果里是不可辨识的。假设我们想在连接轴上创建一个多层级索引,我们需要用到keys
参数:
python">result = pd.concat([s1, s1, s3], keys=['one', 'two', 'three'])
result
one a 0
b 1
two a 0
b 1
three f 5
g 6
dtype: int64
python">result.unstack()
| a | b | f | g |
---|
one | 0.0 | 1.0 | NaN | NaN |
---|
two | 0.0 | 1.0 | NaN | NaN |
---|
three | NaN | NaN | 5.0 | 6.0 |
---|
如果是设定axis=1
,那么keys
会变为DataFrame
的column header
(列头):
python">word">print(s1)
word">print(s2)
word">print(s3)
a 0
b 1
dtype: int64
c 2
d 3
e 4
dtype: int64
f 5
g 6
dtype: int64
python">pd.concat([s1, s2, s3], axis=1, keys=['one', 'two', 'three'])
| one | two | three |
---|
a | 0.0 | NaN | NaN |
---|
b | 1.0 | NaN | NaN |
---|
c | NaN | 2.0 | NaN |
---|
d | NaN | 3.0 | NaN |
---|
e | NaN | 4.0 | NaN |
---|
f | NaN | NaN | 5.0 |
---|
g | NaN | NaN | 6.0 |
---|
这种逻辑也可以扩展到DataFrame对象上:
python">df1 = pd.DataFrame(np.arange(6).reshape(3, 2), index=['a', 'b', 'c'],
columns=['one', 'two'])
df1
python">df2 = pd.DataFrame(5 + np.arange(4).reshape(2, 2), index=['a', 'c'],
columns=['three', 'four'])
df2
python">pd.concat([df1, df2], axis=1, keys=['level1', 'level2'])
| level1 | level2 |
---|
| one | two | three | four |
---|
a | 0 | 1 | 5.0 | 6.0 |
---|
b | 2 | 3 | NaN | NaN |
---|
c | 4 | 5 | 7.0 | 8.0 |
---|
如果导入一个dict
而不是list
,那么dict
的key
会被用于上面concat
中的keys
选项:
python">pd.concat({'level1': df1, 'level2': df2}, axis=1)
| level1 | level2 |
---|
| one | two | three | four |
---|
a | 0 | 1 | 5.0 | 6.0 |
---|
b | 2 | 3 | NaN | NaN |
---|
c | 4 | 5 | 7.0 | 8.0 |
---|
还有其他一些选项负责多层级索引的设定(表8-3)。比如,可以给创建的axis
level
(轴层级)用names
参数来命名:
python">pd.concat([df1, df2], axis=1, keys=['level1', 'level2'],
names=['upper', 'lower'])
upper | level1 | level2 |
---|
lower | one | two | three | four |
---|
a | 0 | 1 | 5.0 | 6.0 |
---|
b | 2 | 3 | NaN | NaN |
---|
c | 4 | 5 | 7.0 | 8.0 |
---|
最后我们关心的是,在DataFrame
中,行索引(row index
)没有包含相关的数据:
python">df1 = pd.DataFrame(np.random.randn(3, 4), columns=['a', 'b', 'c', 'd'])
df1
| a | b | c | d |
---|
0 | 1.049308 | -0.660746 | 1.152071 | -1.447441 |
---|
1 | -0.484170 | -0.096755 | -0.815349 | 1.839818 |
---|
2 | -0.277541 | 0.164721 | -0.012481 | 0.477152 |
---|
python">df2 = pd.DataFrame(np.random.randn(2, 3), columns=['b', 'd', 'a'])
df2
| b | d | a |
---|
0 | -0.556378 | -2.286601 | -0.494776 |
---|
1 | 1.152716 | 0.270165 | -0.222289 |
---|
这种情况下,可以设置ignore_index=True
:
python">pd.concat([df1, df2], ignore_index=True)
| a | b | c | d |
---|
0 | 1.049308 | -0.660746 | 1.152071 | -1.447441 |
---|
1 | -0.484170 | -0.096755 | -0.815349 | 1.839818 |
---|
2 | -0.277541 | 0.164721 | -0.012481 | 0.477152 |
---|
3 | -0.494776 | -0.556378 | NaN | -2.286601 |
---|
4 | -0.222289 | 1.152716 | NaN | 0.270165 |
---|
3 Combining Data with Overlap
另一种数据结合方法既不属于merge
,也不属于concatenation
。比如两个数据集,index
可能完全覆盖,或覆盖一部分。这里举个例子,考虑下numpy
的where
函数,可以在数组上进行类似于if-else
表达式般的判断:
python">a = pd.Series([np.nan, 2.5, np.nan, 3.5, 4.5, np.nan],
index=['f', 'e', 'd', 'c', 'b', 'a'])
a
f NaN
e 2.5
d NaN
c 3.5
b 4.5
a NaN
dtype: float64
python">b = pd.Series(np.arange(len(a), dtype=np.float64),
index=['f', 'e', 'd', 'c', 'b', 'a'])
b
f 0.0
e 1.0
d 2.0
c 3.0
b 4.0
a 5.0
dtype: float64
python">np.where(pd.isnull(a), b, a)
array([ 0. , 2.5, 2. , 3.5, 4.5, 5. ])
Series
有一个combine_first
方法,效果和上面是一样,而且还会自动对齐(比如把index
按字母进行排列):
python">b[:-2].combine_first(a[2:])
a NaN
b 4.5
c 3.0
d 2.0
e 1.0
f 0.0
dtype: float64
对于DataFrame
, combine_first
可以在列与列之间做到同样的事情,可以认为是用传递的对象,给调用对象中的缺失值打补丁:
python">df1 = pd.DataFrame({'a': [1., np.nan, 5., np.nan],
'b': [np.nan, 2., np.nan, 6.],
'c': range(2, 18, 4)})
df1
| a | b | c |
---|
0 | 1.0 | NaN | 2 |
---|
1 | NaN | 2.0 | 6 |
---|
2 | 5.0 | NaN | 10 |
---|
3 | NaN | 6.0 | 14 |
---|
python">df2 = pd.DataFrame({'a': [5., 4., np.nan, 3., 7.],
'b': [np.nan, 3., 4., 6., 8.]})
df2
| a | b |
---|
0 | 5.0 | NaN |
---|
1 | 4.0 | 3.0 |
---|
2 | NaN | 4.0 |
---|
3 | 3.0 | 6.0 |
---|
4 | 7.0 | 8.0 |
---|
python">df1.combine_first(df2)
| a | b | c |
---|
0 | 1.0 | NaN | 2.0 |
---|
1 | 4.0 | 2.0 | 6.0 |
---|
2 | 5.0 | 4.0 | 10.0 |
---|
3 | 3.0 | 6.0 | 14.0 |
---|
4 | 7.0 | 8.0 | NaN |
---|