数据可视化基础专题(二十九):Pandas基础 合并merge
Posted 秋华
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据可视化基础专题(二十九):Pandas基础 合并merge相关的知识,希望对你有一定的参考价值。
Database-style DataFrame or named Series joining/merging
1 summary
pandas provides a single function, merge()
, as the entry point for all standard database join operations between DataFrame
or named Series
objects:
pd.merge( left, right, how="inner", on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=True, suffixes=("_x", "_y"), copy=True, indicator=False, validate=None, )
-
left
: A DataFrame or named Series object. -
right
: Another DataFrame or named Series object. -
on
: Column or index level names to join on. Must be found in both the left and right DataFrame and/or Series objects. If not passed andleft_index
andright_index
areFalse
, the intersection of the columns in the DataFrames and/or Series will be inferred to be the join keys. -
left_on
: Columns or index levels from the left DataFrame or Series to use as keys. Can either be column names, index level names, or arrays with length equal to the length of the DataFrame or Series. -
right_on
: Columns or index levels from the right DataFrame or Series to use as keys. Can either be column names, index level names, or arrays with length equal to the length of the DataFrame or Series. -
left_index
: IfTrue
, use the index (row labels) from the left DataFrame or Series as its join key(s). In the case of a DataFrame or Series with a MultiIndex (hierarchical), the number of levels must match the number of join keys from the right DataFrame or Series. -
right_index
: Same usage asleft_index
for the right DataFrame or Series -
how
: One of\'left\'
,\'right\'
,\'outer\'
,\'inner\'
. Defaults toinner
. See below for more detailed description of each method. -
sort
: Sort the result DataFrame by the join keys in lexicographical order. Defaults toTrue
, setting toFalse
will improve performance substantially in many cases. -
suffixes
: A tuple of string suffixes to apply to overlapping columns. Defaults to(\'_x\', \'_y\')
. -
copy
: Always copy data (defaultTrue
) from the passed DataFrame or named Series objects, even when reindexing is not necessary. Cannot be avoided in many cases but may improve performance / memory usage. The cases where copying can be avoided are somewhat pathological but this option is provided nonetheless. -
indicator
: Add a column to the output DataFrame called_merge
with information on the source of each row._merge
is Categorical-type and takes on a value ofleft_only
for observations whose merge key only appears in\'left\'
DataFrame or Series,right_only
for observations whose merge key only appears in\'right\'
DataFrame or Series, andboth
if the observation’s merge key is found in both. -
validate
: string, default None. If specified, checks if merge is of specified type.-
“one_to_one” or “1:1”: checks if merge keys are unique in both left and right datasets.
-
“one_to_many” or “1:m”: checks if merge keys are unique in left dataset.
-
“many_to_one” or “m:1”: checks if merge keys are unique in right dataset.
-
“many_to_many” or “m:m”: allowed, but does not result in checks.
-
Support for specifying index levels as the on, left_on, and right_on parameters was added in version 0.23.0.
Support for merging named Series objects was added in version 0.24.0.
The return type will be the same as left
. If left
is a DataFrame
or named Series
and right
is a subclass of DataFrame
, the return type will still be DataFrame
.
merge
is a function in the pandas namespace, and it is also available as a DataFrame
instance method merge()
, with the calling DataFrame
being implicitly considered the left object in the join.
The related join()
method, uses merge
internally for the index-on-index (by default) and column(s)-on-index join. If you are joining on index only, you may wish to use DataFrame.join
to save yourself some typing.
2 Brief primer on merge methods (relational algebra)
Experienced users of relational databases like SQL will be familiar with the terminology used to describe join operations between two SQL-table like structures (DataFrame
objects). There are several cases to consider which are very important to understand:
-
one-to-one joins: for example when joining two
DataFrame
objects on their indexes (which must contain unique values). -
many-to-one joins: for example when joining an index (unique) to one or more columns in a different
DataFrame
. -
many-to-many joins: joining columns on columns.
When joining columns on columns (potentially a many-to-many join), any indexes on the passed DataFrame objects will be discarded.
It is worth spending some time understanding the result of the many-to-many join case. In SQL / standard relational algebra, if a key combination appears more than once in both tables, the resulting table will have the Cartesian product of the associated data. Here is a very basic example with one unique key combination:
In [39]: left = pd.DataFrame( ....: { ....: "key": ["K0", "K1", "K2", "K3"], ....: "A": ["A0", "A1", "A2", "A3"], ....: "B": ["B0", "B1", "B2", "B3"], ....: } ....: ) ....: In [40]: right = pd.DataFrame( ....: { ....: "key": ["K0", "K1", "K2", "K3"], ....: "C": ["C0", "C1", "C2", "C3"], ....: "D": ["D0", "D1", "D2", "D3"], ....: } ....: ) ....: In [41]: result = pd.merge(left, right, on="key")
Here is a more complicated example with multiple join keys. Only the keys appearing in left
and right
are present (the intersection), since how=\'inner\'
by default.
In [42]: left = pd.DataFrame( ....: { ....: "key1": ["K0", "K0", "K1", "K2"], ....: "key2": ["K0", "K1", "K0", "K1"], ....: "A": ["A0", "A1", "A2", "A3"], ....: "B": ["B0", "B1", "B2", "B3"], ....: } ....: ) ....: In [43]: right = pd.DataFrame( ....: { ....: "key1": ["K0", "K1", "K1", "K2"], ....: "key2": ["K0", "K0", "K0", "K0"], ....: "C": ["C0", "C1", "C2", "C3"], ....: "D": ["D0", "D1", "D2", "D3"], ....: } ....: ) ....: In [44]: result = pd.merge(left, right, on=["key1", "key2"])
The how
argument to merge
specifies how to determine which keys are to be included in the resulting table. If a key combination does not appear in either the left or right tables, the values in the joined table will be NA
. Here is a summary of the how
options and their SQL equivalent names:
In [45]: result = pd.merge(left, right, how="left", on=["key1", "key2"])
In [46]: result = pd.merge(left, right, how="right", on=["key1", "key2"])
In [47]: result = pd.merge(left, right, how="outer", on=["key1", "key2"])
In [48]: result = pd.merge(left, right, how="inner", on=["key1", "key2"])
You can merge a mult-indexed Series and a DataFrame, if the names of the MultiIndex correspond to the columns from the DataFrame. Transform the Series to a DataFrame using Series.reset_index()
before merging, as shown in the following example.
In [49]: df = pd.DataFrame({"Let": ["A", "B", "C"], "Num": [1, 2, 3]}) In [50]: df Out[50]: Let Num 0 A 1 1 B 2 2 C 3 In [51]: ser = pd.Series( ....: ["a", "b", "c", "d", "e", "f"], ....: index=pd.MultiIndex.from_arrays( ....: [["A", "B", "C"] * 2, [1, 2, 3, 4, 5, 6]], names=["Let", "Num"] ....: ), ....: ) ....: In [52]: ser Out[52]: Let Num A 1 a B 2 b C 3 c A 4 d B 5 e C 6 f dtype: object In [53]: pd.merge(df, ser.reset_index(), on=["Let", "Num"]) Out[53]: Let Num 0 0 A 1 a 1 B 2 b 2 C 3 c
Here is another example with duplicate join keys in DataFrames:
In [54]: left = pd.DataFrame({"A": [1, 2], "B": [2, 2]}) In [55]: right = pd.DataFrame({"A": [4, 5, 6], "B": [2, 2, 2]}) In [56]: result = pd.merge(left, right, on="B", how="outer")
3 Checking for duplicate keys
Users can use the validate
argument to automatically check whether there are unexpected duplicates in their merge keys. Key uniqueness is checked before merge operations and so should protect against memory overflows. Checking key uniqueness is also a good way to ensure user data structures are as expected.
In the following example, there are duplicate values of B
in the right DataFrame
. As this is not a one-to-one merge – as specified in the validate
argument – an exception will be raised.
In [57]: left = pd.DataFrame({"A": [1, 2], "B": [1, 2]}) In [58]: right = pd.DataFrame({"A": [4, 5, 6], "B": [2, 2, 2]})
In [53]: result = pd.merge(left, right, on="B", how="outer", validate="one_to_one") ... MergeError: Merge keys are not unique in right dataset; not a one-to-one merge
If the user is aware of the duplicates in the right DataFrame
but wants to ensure there are no duplicates in the left DataFrame, one can use the validate=\'one_to_many\'
argument instead, which will not raise an exception.
In [59]: pd.merge(left, right, on="B", how="outer", validate="one_to_many") Out[59]: A_x B A_y 0 1 1 NaN 1 2 2 4.0 2 2 2 5.0 3 2 2 6.0
4 The merge indicator
merge()
accepts the argument indicator
. If True
, a Categorical-type column called _merge
will be added to the output object that takes on values:
In [60]: df1 = pd.DataFrame({"col1": [0, 1], "col_left": ["a", "b"]}) In [61]: df2 = pd.DataFrame({"col1": [1, 2, 2], "col_right": [2, 2, 2]}) In [62]: pd.merge(df1, df2, on="col1", how="outer", indicator=True) Out[62]: col1 col_left col_right _merge 0 0 a NaN left_only 1 1 b 2.0 both 2 2 NaN 2.0 right_only 3 2 NaN 2.0 right_only
The indicator
argument will also accept string arguments, in which case the indicator function will use the value of the passed string as the name for the indicator column.
In [63]: pd.merge(df1, df2, on="col1", how="outer", indicator="indicator_column") Out[63]: col1 col_left col_right indicator_column 0 0 a NaN left_only 1 1 b 2.0 both 2 2 NaN 2.0 right_only 3 2 NaN 2.0 right_only
5 Merge dtypes
Merging will preserve the dtype of the join keys.
In [64]: left = pd.DataFrame({"key": [1], "v1": [10]}) In [65]: left Out[65]: key v1 0 1 10 In [66]: right = pd.DataFrame({"key": [1, 2], "v1": [20, 30]}) In [67]: right Out[67]: key v1 0 1 20 1 2 30
We are able to preserve the join keys:
In [68]: pd.merge(left, right, how="outer") Out[68]: key v1 0 1 10 1 1 20 2 2 30 In [69]: pd.merge(left, right, how="outer").dtypes Out[69]: key int64 v1 int64 dtype: object
Of course if you have missing values that are introduced, then the resulting dtype will be upcast.
In [70]: pd.merge(left, right, how="outer", on="key") Out[70]: key v1_x v1_y 0 1 10.0 20 1 2 NaN 30 In [71]: pd.merge(left, right, how="outer", on="key").dtypes Out[71]: key int64 v1_x float64 v1_y int64 dtype: object
Merging will preserve category
dtypes of the mergands. See also the section on categoricals.
The left frame.
In [72]: from pandas.api.types import CategoricalDtype In [73]: X = pd.Series(np.random.choice(["foo", "bar"], size=(10,))) In [74]: X = X.astype(CategoricalDtype(categories=["foo", "bar"])) In [75]: left = pd.DataFrame( ....: {"X": X, "Y": np.random.choice(["one", "two", "three"], size=(10,))} ....: ) ....: In [76]: left Out[76]: X Y 0 bar one 1 foo one 2 foo three 3 bar three 4 foo one 5 bar one 6 bar three 7 bar three 8 bar three 9 foo three In [77]: left.dtypes Out[77]: X category Y object dtype: object
The right frame.
In [78]: right = pd.DataFrame( ....: { ....: "X": pd.Series(["foo", "bar"], dtype=CategoricalDtype(["foo", "bar"])), ....: "Z": [1, 2], ....: } ....: ) ....: In [79]: right Out[79]: X Z 0 foo 1 1 bar 2 In [80]: right.dtypes Out[80]: X category Z int64 dtype: object
The merged result:
In [81]: result = pd.merge(left, right, how="outer") In [82]: result Out[82]: X Y Z 0 bar one 2 1 bar three 2 2 bar one 2 3 bar three 2 4 bar three 2 5 bar three 2 6 foo one 1 7 foo three 1 8 foo one 1 9 foo three 1 In [83]: result.dtypes Out[83]: X category Y object Z int64 dtype: object
6 Joining on index
DataFrame.join()
is a convenient method for combining the columns of two potentially differently-indexed DataFrames
into a single result DataFrame
. Here is a very basic example:
In [84]: left = pd.DataFrame( ....: {"A": ["A0", "A1", "A2"], "B": ["B0", "B1", "B2"]}, index=["K0", "K1", "K2"] ....: ) ....: In [85]: right = pd.DataFrame( ....: {"C": ["C0", "C2", "C3"], "D": ["D0", "D2", "D3"]}, index=["K0", "K2", "K3"] ....: ) ....: In [86]: result = left.join(right)
In [87]: result = left.join(right, how="outer")
The same as above, but with how=\'inner\'
.
In [88]: result = left.join(right, how="inner")
The data alignment here is on the indexes (row labels). This same behavior can be achieved using merge
plus additional arguments instructing it to use the indexes:
In [89]: result = pd.merge(left, right, left_index=True, right_index=True, how="outer")
In [90]: result = pd.merge(left, right, left_index=True, right_index=True, how="inner")
以上是关于数据可视化基础专题(二十九):Pandas基础 合并merge的主要内容,如果未能解决你的问题,请参考以下文章
大厂Java核心面试知识点整理,二十九个专题任你挑,美滋滋~