python的concat函数_python – Pandas的concat函数中的’levels’,’...

在为自己回答这个问题的过程中,我学到了很多东西,我想把一组例子和一些解释放在一起.

关于水平论点的具体答案将趋于结束.

pandas.concat:失踪手册

导入和定义对象

import pandas as pd

d1 = pd.DataFrame(dict(A=.1, B=.2, C=.3), index=[2, 3])

d2 = pd.DataFrame(dict(B=.4, C=.5, D=.6), index=[1, 2])

d3 = pd.DataFrame(dict(A=.7, B=.8, D=.9), index=[1, 3])

s1 = pd.Series([1, 2], index=[2, 3])

s2 = pd.Series([3, 4], index=[1, 2])

s3 = pd.Series([5, 6], index=[1, 3])

参数

OBJ文件

我们遇到的第一个论点是objs:

objs: a sequence or mapping of Series, DataFrame, or Panel objects

If a dict is passed, the sorted keys will be used as the keys argument, unless it is passed, in which case the values will be selected (see below). Any None objects will be dropped silently unless they are all None in which case a ValueError will be raised

>我们通常会看到这与Series或DataFrame对象列表一起使用.

>我会证明dict也非常有用.

>也可以使用生成器,在map中使用map时可能很有用(f,list_of_df)

现在,我们将坚持上面定义的一些DataFrame和Series对象的列表.

我将展示如何利用字典来提供非常有用的MultiIndex结果.

pd.concat([d1, d2])

A B C D

2 0.1 0.2 0.3 NaN

3 0.1 0.2 0.3 NaN

1 NaN 0.4 0.5 0.6

2 NaN 0.4 0.5 0.6

我们遇到的第二个参数是axis,其默认值为0:

axis: {0/’index’, 1/’columns’}, default 0

The axis to concatenate along.

轴= 0的两个DataFrame(堆叠)

对于0或索引的值,我们的意思是:“沿着列对齐并添加到索引”.

如上所示我们使用axis = 0,因为0是默认值,并且我们看到d2的索引扩展了d1的索引,尽管值2重叠:

pd.concat([d1, d2], axis=0)

A B C D

2 0.1 0.2 0.3 NaN

3 0.1 0.2 0.3 NaN

1 NaN 0.4 0.5 0.6

2 NaN 0.4 0.5 0.6

轴= 1的两个DataFrame(并排)

对于值1或列,我们的意思是:“沿着索引对齐并添加到列”,

pd.concat([d1, d2], axis=1)

A B C B C D

1 NaN NaN NaN 0.4 0.5 0.6

2 0.1 0.2 0.3 0.4 0.5 0.6

3 0.1 0.2 0.3 NaN NaN NaN

我们可以看到结果索引是索引的并集,结果列是d1列的d2列的扩展.

两个(或三个)系列轴= 0(堆叠)

当组合pandas.Series沿轴= 0时,我们得到一个pandas.Series.除非所有组合的系列具有相同的名称,否则生成的系列的名称将为None.打印出结果系列时,请注意’名称:A’.如果不存在,我们可以假设系列名称为None.

| | | pd.concat(

| pd.concat( | pd.concat( | [s1.rename('A'),

pd.concat( | [s1.rename('A'), | [s1.rename('A'), | s2.rename('B'),

[s1, s2]) | s2]) | s2.rename('A')]) | s3.rename('A')])

-------------- | --------------------- | ---------------------- | ----------------------

2 1 | 2 1 | 2 1 | 2 1

3 2 | 3 2 | 3 2 | 3 2

1 3 | 1 3 | 1 3 | 1 3

2 4 | 2 4 | 2 4 | 2 4

dtype: int64 | dtype: int64 | Name: A, dtype: int64 | 1 5

| | | 3 6

| | | dtype: int64

两个(或三个)系列轴= 1(并排)

当组合pandas.Series沿轴= 1时,它是我们引用的name属性,以便在生成的pandas.DataFrame中推断列名.

| | pd.concat(

| pd.concat( | [s1.rename('X'),

pd.concat( | [s1.rename('X'), | s2.rename('Y'),

[s1, s2], axis=1) | s2], axis=1) | s3.rename('Z')], axis=1)

---------------------- | --------------------- | ------------------------------

0 1 | X 0 | X Y Z

1 NaN 3.0 | 1 NaN 3.0 | 1 NaN 3.0 5.0

2 1.0 4.0 | 2 1.0 4.0 | 2 1.0 4.0 NaN

3 2.0 NaN | 3 2.0 NaN | 3 2.0 NaN 6.0

混合系列和DataFrame,轴= 0(堆叠)

当沿着轴= 0执行Series和DataFrame的串联时,我们将所有Seri??es转换为单列DataFrame.

请特别注意,这是沿轴= 0的连接;这意味着在对齐列时扩展索引(行).在下面的例子中,我们看到指数变为[2,3,2,3],这是指数的不加选择的附加.除非我使用to_frame参数强制命名Series列,否则列不会重叠:

pd.concat( |

[s1.to_frame(), d1]) | pd.concat([s1, d1])

------------------------- | ---------------------

0 A B C | 0 A B C

2 1.0 NaN NaN NaN | 2 1.0 NaN NaN NaN

3 2.0 NaN NaN NaN | 3 2.0 NaN NaN NaN

2 NaN 0.1 0.2 0.3 | 2 NaN 0.1 0.2 0.3

3 NaN 0.1 0.2 0.3 | 3 NaN 0.1 0.2 0.3

您可以看到pd.concat([s1,d1])的结果与我自己穿孔to_frame的结果相同.

但是,我可以使用to_frame参数控制结果列的名称.使用重命名方法重命名Series不会控制生成的DataFrame中的列名.

# Effectively renames | |

# `s1` but does not align | # Does not rename. So | # Renames to something

# with columns in `d1` | # Pandas defaults to `0` | # that does align with `d1`

pd.concat( | pd.concat( | pd.concat(

[s1.to_frame('X'), d1]) | [s1.rename('X'), d1]) | [s1.to_frame('B'), d1])

---------------------------- | -------------------------- | ----------------------------

A B C X | 0 A B C | A B C

2 NaN NaN NaN 1.0 | 2 1.0 NaN NaN NaN | 2 NaN 1.0 NaN

3 NaN NaN NaN 2.0 | 3 2.0 NaN NaN NaN | 3 NaN 2.0 NaN

2 0.1 0.2 0.3 NaN | 2 NaN 0.1 0.2 0.3 | 2 0.1 0.2 0.3

3 0.1 0.2 0.3 NaN | 3 NaN 0.1 0.2 0.3 | 3 0.1 0.2 0.3

混合系列和DataFrame,轴= 1(并排)

这非常直观.当name属性不可用时,Series列名默认为此类Series对象的枚举.

| pd.concat(

pd.concat( | [s1.rename('X'),

[s1, d1], | s2, s3, d1],

axis=1) | axis=1)

------------------- | -------------------------------

0 A B C | X 0 1 A B C

2 1 0.1 0.2 0.3 | 1 NaN 3.0 5.0 NaN NaN NaN

3 2 0.1 0.2 0.3 | 2 1.0 4.0 NaN 0.1 0.2 0.3

| 3 2.0 NaN 6.0 0.1 0.2 0.3

加入

第三个参数是join,它描述了生成的合并是外部合并(默认)还是内部合并.

join: {‘inner’, ‘outer’}, default ‘outer’

How to handle indexes on other axis(es).

事实证明,没有左或右选项,因为pd.concat可以处理的不仅仅是两个要合并的对象.

在d1和d2的情况下,选项看起来像:

pd.concat([d1, d2], axis=1, join='outer')

A B C B C D

1 NaN NaN NaN 0.4 0.5 0.6

2 0.1 0.2 0.3 0.4 0.5 0.6

3 0.1 0.2 0.3 NaN NaN NaN

pd.concat([d1, d2], axis=1, join='inner')

A B C B C D

2 0.1 0.2 0.3 0.4 0.5 0.6

join_axes

第四个参数是允许我们进行左合并的事情.

join_axes: list of Index objects

Specific indexes to use for the other n – 1 axes instead of performing inner/outer set logic.

左合并

pd.concat([d1, d2, d3], axis=1, join_axes=[d1.index])

A B C B C D A B D

2 0.1 0.2 0.3 0.4 0.5 0.6 NaN NaN NaN

3 0.1 0.2 0.3 NaN NaN NaN 0.7 0.8 0.9

合并

pd.concat([d1, d2, d3], axis=1, join_axes=[d3.index])

A B C B C D A B D

1 NaN NaN NaN 0.4 0.5 0.6 0.7 0.8 0.9

3 0.1 0.2 0.3 NaN NaN NaN 0.7 0.8 0.9

ignore_index

ignore_index: boolean, default False

If True, do not use the index values along the concatenation axis. The resulting axis will be labeled 0, …, n – 1. This is useful if you are concatenating objects where the concatenation axis does not have meaningful indexing information. Note the index values on the other axes are still respected in the join.

就像我在d2上堆叠d1一样,如果我不关心索引值,我可以重置它们或忽略它们.

| pd.concat( | pd.concat(

| [d1, d2], | [d1, d2]

pd.concat([d1, d2]) | ignore_index=True) | ).reset_index(drop=True)

--------------------- | ----------------------- | -------------------------

A B C D | A B C D | A B C D

2 0.1 0.2 0.3 NaN | 0 0.1 0.2 0.3 NaN | 0 0.1 0.2 0.3 NaN

3 0.1 0.2 0.3 NaN | 1 0.1 0.2 0.3 NaN | 1 0.1 0.2 0.3 NaN

1 NaN 0.4 0.5 0.6 | 2 NaN 0.4 0.5 0.6 | 2 NaN 0.4 0.5 0.6

2 NaN 0.4 0.5 0.6 | 3 NaN 0.4 0.5 0.6 | 3 NaN 0.4 0.5 0.6

当使用axis = 1时:

| pd.concat(

| [d1, d2], axis=1,

pd.concat([d1, d2], axis=1) | ignore_index=True)

------------------------------- | -------------------------------

A B C B C D | 0 1 2 3 4 5

1 NaN NaN NaN 0.4 0.5 0.6 | 1 NaN NaN NaN 0.4 0.5 0.6

2 0.1 0.2 0.3 0.4 0.5 0.6 | 2 0.1 0.2 0.3 0.4 0.5 0.6

3 0.1 0.2 0.3 NaN NaN NaN | 3 0.1 0.2 0.3 NaN NaN NaN

按键

我们可以传递标量值或元组列表,以便将元组或标量值分配给相应的MultiIndex.传递列表的长度必须与连接的项目数相同.

keys: sequence, default None

If multiple levels passed, should contain tuples. Construct hierarchical index using the passed keys as the outermost level

轴= 0

沿着轴= 0(扩展索引)连接Series对象时.

这些键成为index属性中MultiIndex对象的新初始级别.

# length 3 length 3 # length 2 length 2

# /--------\ /-----------\ # /----\ /------\

pd.concat([s1, s2, s3], keys=['A', 'B', 'C']) pd.concat([s1, s2], keys=['A', 'B'])

---------------------------------------------- -------------------------------------

A 2 1 A 2 1

3 2 3 2

B 1 3 B 1 3

2 4 2 4

C 1 5 dtype: int64

3 6

dtype: int64

但是,我们可以在keys参数中使用多个标量值来创建更深的MultiIndex.这里我们传递长度为2的元组,前两个MultiIndex的新级别:

pd.concat(

[s1, s2, s3],

keys=[('A', 'X'), ('A', 'Y'), ('B', 'X')])

-----------------------------------------------

A X 2 1

3 2

Y 1 3

2 4

B X 1 5

3 6

dtype: int64

轴= 1

沿列扩展时有点不同.当我们使用axis = 0(见上文)时,除现有索引外,我们的键还充当MultiIndex级别.对于axis = 1,我们指的是Series对象没有的轴,即columns属性.

两个系列的变化轴= 1

请注意,只要没有传递密钥,命名s1和s2就很重要,但如果传递了密钥则会被覆盖.

| | | pd.concat(

| pd.concat( | pd.concat( | [s1.rename('U'),

pd.concat( | [s1, s2], | [s1.rename('U'), | s2.rename('V')],

[s1, s2], | axis=1, | s2.rename('V')], | axis=1,

axis=1) | keys=['X', 'Y']) | axis=1) | keys=['X', 'Y'])

-------------- | --------------------- | ---------------------- | ----------------------

0 1 | X Y | U V | X Y

1 NaN 3.0 | 1 NaN 3.0 | 1 NaN 3.0 | 1 NaN 3.0

2 1.0 4.0 | 2 1.0 4.0 | 2 1.0 4.0 | 2 1.0 4.0

3 2.0 NaN | 3 2.0 NaN | 3 2.0 NaN | 3 2.0 NaN

具有系列和轴的MultiIndex = 1

pd.concat(

[s1, s2],

axis=1,

keys=[('W', 'X'), ('W', 'Y')])

-----------------------------------

W

X Y

1 NaN 3.0

2 1.0 4.0

3 2.0 NaN

两个DataFrame,轴= 1

与axis = 0示例一样,键将级别添加到MultiIndex,但这次添加到存储在columns属性中的对象.

pd.concat( | pd.concat(

[d1, d2], | [d1, d2],

axis=1, | axis=1,

keys=['X', 'Y']) | keys=[('First', 'X'), ('Second', 'X')])

------------------------------- | --------------------------------------------

X Y | First Second

A B C B C D | X X

1 NaN NaN NaN 0.4 0.5 0.6 | A B C B C D

2 0.1 0.2 0.3 0.4 0.5 0.6 | 1 NaN NaN NaN 0.4 0.5 0.6

3 0.1 0.2 0.3 NaN NaN NaN | 2 0.1 0.2 0.3 0.4 0.5 0.6

| 3 0.1 0.2 0.3 NaN NaN NaN

系列和DataFrame,轴= 1

这很棘手.在这种情况下,标量键值在成为列时不能充当Series对象的唯一索引级别,同时也充当DataFrame的MultiIndex的第一级别.因此,Pandas将再次使用Series对象的name属性作为列名的来源.

pd.concat( | pd.concat(

[s1, d1], | [s1.rename('Z'), d1],

axis=1, | axis=1,

keys=['X', 'Y']) | keys=['X', 'Y'])

--------------------- | --------------------------

X Y | X Y

0 A B C | Z A B C

2 1 0.1 0.2 0.3 | 2 1 0.1 0.2 0.3

3 2 0.1 0.2 0.3 | 3 2 0.1 0.2 0.3

键和MultiIndex的局限性.

Pandas似乎只是从系列名称中推断出列名,但在具有不同列级别的数据帧之间进行类似级联时,它不会填充空白.

d1_ = pd.concat(

[d1], axis=1,

keys=['One'])

d1_

One

A B C

2 0.1 0.2 0.3

3 0.1 0.2 0.3

然后将此与另一个数据框连接在一起,在columns对象中只有一个级别,Pandas将拒绝尝试创建MultiIndex对象的元组并组合所有数据框,就像单个级别的对象,标量和元组一样.

pd.concat([d1_, d2], axis=1)

(One, A) (One, B) (One, C) B C D

1 NaN NaN NaN 0.4 0.5 0.6

2 0.1 0.2 0.3 0.4 0.5 0.6

3 0.1 0.2 0.3 NaN NaN NaN

传递dict而不是列表

传递字典时,pandas.concat将使用字典中的键作为键参数.

# axis=0 | # axis=1

pd.concat( | pd.concat(

{0: d1, 1: d2}) | {0: d1, 1: d2}, axis=1)

----------------------- | -------------------------------

A B C D | 0 1

0 2 0.1 0.2 0.3 NaN | A B C B C D

3 0.1 0.2 0.3 NaN | 1 NaN NaN NaN 0.4 0.5 0.6

1 1 NaN 0.4 0.5 0.6 | 2 0.1 0.2 0.3 0.4 0.5 0.6

2 NaN 0.4 0.5 0.6 | 3 0.1 0.2 0.3 NaN NaN NaN

水平

这与keys参数一起使用.当级别保留为其默认值None时,Pandas将获取生成的MultiIndex的每个级别的唯一值,并将其用作生成的index.levels属性中使用的对象.

levels: list of sequences, default None

Specific levels (unique values) to use for constructing a MultiIndex. Otherwise they will be inferred from the keys.

如果熊猫已经推断出这些水平应该是什么,那么我们有什么优势来指定它?我将展示一个示例,并让您自己思考为什么这可能有用的其他原因.

根据文档,levels参数是序列列表.这意味着我们可以使用另一个pandas.Index作为其中一个序列.

考虑数据帧df,它是d1,d2和d3的串联:

df = pd.concat(

[d1, d2, d3], axis=1,

keys=['First', 'Second', 'Fourth'])

df

First Second Fourth

A B C B C D A B D

1 NaN NaN NaN 0.4 0.5 0.6 0.7 0.8 0.9

2 0.1 0.2 0.3 0.4 0.5 0.6 NaN NaN NaN

3 0.1 0.2 0.3 NaN NaN NaN 0.7 0.8 0.9

列对象的级别为:

print(df, *df.columns.levels, sep='\n')

Index(['First', 'Second', 'Fourth'], dtype='object')

Index(['A', 'B', 'C', 'D'], dtype='object')

如果我们在groupby中使用sum,我们得到:

df.groupby(axis=1, level=0).sum()

First Fourth Second

1 0.0 2.4 1.5

2 0.6 0.0 1.5

3 0.6 2.4 0.0

但如果不是[‘First’,’Second’,’Fourth’]又有另外一个名为Third和Fifth的缺失类别呢?我希望它们包含在groupby聚合的结果中?如果我们有一个pandas.CategoricalIndex,我们可以这样做.我们可以提前指定levels参数.

所以相反,让我们将df定义为:

cats = ['First', 'Second', 'Third', 'Fourth', 'Fifth']

lvl = pd.CategoricalIndex(cats, categories=cats, ordered=True)

df = pd.concat(

[d1, d2, d3], axis=1,

keys=['First', 'Second', 'Fourth'],

levels=[lvl]

)

df

First Fourth Second

1 0.0 2.4 1.5

2 0.6 0.0 1.5

3 0.6 2.4 0.0

但是column对象的第一级是:

df.columns.levels[0]

CategoricalIndex(

['First', 'Second', 'Third', 'Fourth', 'Fifth'],

categories=['First', 'Second', 'Third', 'Fourth', 'Fifth'],

ordered=True, dtype='category')

我们的groupby总结如下:

df.groupby(axis=1, level=0).sum()

First Second Third Fourth Fifth

1 0.0 1.5 0.0 2.4 0.0

2 0.6 1.5 0.0 0.0 0.0

3 0.6 0.0 0.0 2.4 0.0

这用于命名生成的MultiIndex的级别.名称列表的长度应与生成的MultiIndex中的级别数相匹配.

names: list, default None

Names for the levels in the resulting hierarchical index

# axis=0 | # axis=1

pd.concat( | pd.concat(

[d1, d2], | [d1, d2],

keys=[0, 1], | axis=1, keys=[0, 1],

names=['lvl0', 'lvl1']) | names=['lvl0', 'lvl1'])

----------------------------- | ----------------------------------

A B C D | lvl0 0 1

lvl0 lvl1 | lvl1 A B C B C D

0 2 0.1 0.2 0.3 NaN | 1 NaN NaN NaN 0.4 0.5 0.6

3 0.1 0.2 0.3 NaN | 2 0.1 0.2 0.3 0.4 0.5 0.6

1 1 NaN 0.4 0.5 0.6 | 3 0.1 0.2 0.3 NaN NaN NaN

2 NaN 0.4 0.5 0.6 |

verify_integrity

自解释文件

verify_integrity: boolean, default False

Check whether the new concatenated axis contains duplicates. This can be very expensive relative to the actual data concatenation.

因为连接d1和d2的结果索引不是唯一的,所以它将无法通过完整性检查.

pd.concat([d1, d2])

A B C D

2 0.1 0.2 0.3 NaN

3 0.1 0.2 0.3 NaN

1 NaN 0.4 0.5 0.6

2 NaN 0.4 0.5 0.6

pd.concat([d1, d2], verify_integrity=True)

>

????ValueError:索引具有重叠值:[2]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值