Python 数据处理 —— pandas 合并连接之 concat

前言

pandas 提供了各种工具,可以轻松地将不同的 SeriesDataFrame 连接、合并在一起

此外,pandas 还提供了比较两个 SeriesDataFrame 对象差异的实用工具

连接对象

concat() 函数能够沿指定轴执行连接操作,同时对其他轴上的索引(如果有的话,Series 只有一个轴)执行可选的集合运算(并集或交集)

下面是一个简单的示例

In [1]: df1 = pd.DataFrame(
   ...:     {
   ...:         "A": ["A0", "A1", "A2", "A3"],
   ...:         "B": ["B0", "B1", "B2", "B3"],
   ...:         "C": ["C0", "C1", "C2", "C3"],
   ...:         "D": ["D0", "D1", "D2", "D3"],
   ...:     },
   ...:     index=[0, 1, 2, 3],
   ...: )
   ...: 

In [2]: df2 = pd.DataFrame(
   ...:     {
   ...:         "A": ["A4", "A5", "A6", "A7"],
   ...:         "B": ["B4", "B5", "B6", "B7"],
   ...:         "C": ["C4", "C5", "C6", "C7"],
   ...:         "D": ["D4", "D5", "D6", "D7"],
   ...:     },
   ...:     index=[4, 5, 6, 7],
   ...: )
   ...: 

In [3]: df3 = pd.DataFrame(
   ...:     {
   ...:         "A": ["A8", "A9", "A10", "A11"],
   ...:         "B": ["B8", "B9", "B10", "B11"],
   ...:         "C": ["C8", "C9", "C10", "C11"],
   ...:         "D": ["D8", "D9", "D10", "D11"],
   ...:     },
   ...:     index=[8, 9, 10, 11],
   ...: )
   ...: 

In [4]: frames = [df1, df2, df3]

In [5]: result = pd.concat(frames)

就像 ndarrays 上的函数 numpy.concatenate 一样,pandas.concat 接收一个相同类型的对象列表或字典,并通过一些配置来设置处理方式并将它们连接起来

pd.concat(
    objs,
    axis=0,
    join="outer",
    ignore_index=False,
    keys=None,
    levels=None,
    names=None,
    verify_integrity=False,
    copy=True,
)

让我们再来看看上面的例子。假设我们想将特定的键与被切割的 DataFrame 的每一个片段关联起来。我们可以使用 keys 参数来实现。

In [6]: result = pd.concat(frames, keys=["x", "y", "z"])

从图中可以看出,在结果对象的索引的最外层添加了相应的索引(变为层次索引)。这意味着我们现在可以按键选择每个块

In [7]: result.loc["y"]
Out[7]: 
    A   B   C   D
4  A4  B4  C4  D4
5  A5  B5  C5  D5
6  A6  B6  C6  D6
7  A7  B7  C7  D7

下面将详细介绍此功能

注意

concat()append() 都会对数据进行完整的复制,不断重复使用这个函数会造成显著的性能下降。

如果你想在多个数据集上执行该操作,可以使用列表推导式。

frames = [ process_your_file(f) for f in files ]
result = pd.concat(frames)

同时,当在指定轴上连接 DataFrames 时,pandas 将尽可能尝试保留这些索引或列名。

1 在其他轴上的设置逻辑

当将多个 DataFrame 连接在一起时,您可以通过以下两种方式来选择如何处理其他轴上的数据(即除被连接的轴外)。

  • 并集 join='outer',这是默认选项,因为它不会丢失信息
  • 交集 join='inner'

下面是这些方法的一个示例。首先,对于默认的 join='outer'

In [8]: df4 = pd.DataFrame(
   ...:     {
   ...:         "B": ["B2", "B3", "B6", "B7"],
   ...:         "D": ["D2", "D3", "D6", "D7"],
   ...:         "F": ["F2", "F3", "F6", "F7"],
   ...:     },
   ...:     index=[2, 3, 6, 7],
   ...: )
   ...: 

In [9]: result = pd.concat([df1, df4], axis=1)

对于 join='inner' 也是一样的

In [10]: result = pd.concat([df1, df4], axis=1, join="inner")

最后,假设我们只是想重用原始 DataFrame 中的确切索引

In [11]: result = pd.concat([df1, df4], axis=1).reindex(df1.index)

类似地,我们可以在连接之前进行索引

In [12]: pd.concat([df1, df4.reindex(df1.index)], axis=1)
Out[12]: 
    A   B   C   D    B    D    F
0  A0  B0  C0  D0  NaN  NaN  NaN
1  A1  B1  C1  D1  NaN  NaN  NaN
2  A2  B2  C2  D2   B2   D2   F2
3  A3  B3  C3  D3   B3   D3   F3

2 使用 append 连接

SeriesDataFrame 上的 append() 实例方法是 concat() 的一个简单的快捷方式。

该方法实际上早于 concat。它沿着 axis=0 即索引方向进行连接

In [13]: result = df1.append(df2)

DataFrame 中,索引必须是不相交的,但列不需要

In [14]: result = df1.append(df4, sort=False)

append 可以接受多个对象来进行连接

In [15]: result = df1.append([df2, df3])

注意

这里的 append() 方法不同于 list,该方法不会修改 df1 的值,同时返回是添加 df2 后的拷贝

3 忽略连接轴上的索引

对于某些 DataFrame 对象,其上的索引并没有任何意义,同时你可能希望在连接的时候,忽略这些对象的索引可能存在重叠的情况。

要做到这一点,可以使用 ignore_index 参数

In [16]: result = pd.concat([df1, df4], ignore_index=True, sort=False)

这也是 DataFrame.append() 的一个有效参数

In [17]: result = df1.append(df4, ignore_index=True, sort=False)

4 不同维度数据的连接

您也可以将 SeriesDataFrame 对象连接起来。Series 将被转换为 DataFrame,列名为 Series 的名称

In [18]: s1 = pd.Series(["X0", "X1", "X2", "X3"], name="X")

In [19]: result = pd.concat([df1, s1], axis=1)

对于未命名的 Series,对应的列名将是连续增长的数字

In [20]: s2 = pd.Series(["_0", "_1", "_2", "_3"])

In [21]: result = pd.concat([df1, s2, s2, s2], axis=1)

传递 ignore_index=True 将删除所有名称引用

In [22]: result = pd.concat([df1, s1], axis=1, ignore_index=True)

5 使用 keys 连接

keys 参数的一个常见的用法是,基于现有 Series 创建新 DataFrame 时覆盖列名

默认的行为是如果 Series 的名称存在的话,让生成的 DataFrame 继承

In [23]: s3 = pd.Series([0, 1, 2, 3], name="foo")

In [24]: s4 = pd.Series([0, 1, 2, 3])

In [25]: s5 = pd.Series([0, 1, 4, 5])

In [26]: pd.concat([s3, s4, s5], axis=1)
Out[26]: 
   foo  0  1
0    0  0  0
1    1  1  1
2    2  2  4
3    3  3  5

通过 keys 参数,我们可以覆盖现有的列名

In [27]: pd.concat([s3, s4, s5], axis=1, keys=["red", "blue", "yellow"])
Out[27]: 
   red  blue  yellow
0    0     0       0
1    1     1       1
2    2     2       4
3    3     3       5

让我们考虑第一个例子的一个变体

In [28]: result = pd.concat(frames, keys=["x", "y", "z"])

你也可以在 concat 中传递一个字典,在这种情况下,字典的键将用于 keys 参数(除非指定了其他键)

In [29]: pieces = {"x": df1, "y": df2, "z": df3}

In [30]: result = pd.concat(pieces)

In [31]: result = pd.concat(pieces, keys=["z", "y"])

结果中创建了 MultiIndex,最外层为 keys 参数指定的值,而原 DataFrame 的索引在内层保留了下来

In [32]: result.index.levels
Out[32]: FrozenList([['z', 'y'], [4, 5, 6, 7, 8, 9, 10, 11]])

如果你想指定其他级别,可以使用 levels 参数:

In [33]: result = pd.concat(
   ....:     pieces, keys=["x", "y", "z"], levels=[["z", "y", "x", "w"]], names=["group_key"]
   ....: )
   ....: 

In [34]: result.index.levels
Out[34]: FrozenList([['z', 'y', 'x', 'w'], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]])

6 将行追加到DataFrame

虽然这样做效率很低,但是你可以通过传递一个 Seriesdict 并将其追加到 DataFrame 中,同时会返回一个新的 DataFrame

In [35]: s2 = pd.Series(["X0", "X1", "X2", "X3"], index=["A", "B", "C", "D"])

In [36]: result = df1.append(s2, ignore_index=True)

你应该使用 ignore_index 来指示 DataFrame 丢弃它的索引。

如果你希望保留索引,你应该为 DataFrame 构造一个合适的索引,然后追加或连接这些对象

你也可以传递字典或 Series 列表:

In [37]: dicts = [{"A": 1, "B": 2, "C": 3, "X": 4}, {"A": 5, "B": 6, "C": 7, "Y": 8}]

In [38]: result = df1.append(dicts, ignore_index=True, sort=False)

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Pandas是一个Python库,用于数据处理和分析。在数据分析中,预处理是非常重要的一步,因为它可以帮助我们清洗和转换数据,使其更适合进行分析。Pandas提供了一些强大的预处理功能,包括数据清洗、数据转换、数据重塑和数据合并等。在使用Pandas进行数据分析时,预处理是必不可少的一步。 ### 回答2: 在数据分析中,数据的预处理是一个必要的过程。它的主要目的是清洗数据,准备数据,以便后续分析。在Python中,pandas是一种广泛使用的数据处理库。pandas可以通过其高效的数据结构和操作方法来清洗和处理数据。在本文中,将介绍pandas预处理的一些常见技术。 一、读取数据 在pandas中,使用read_csv()函数读取CSV格式的数据文件,read_excel()函数读取Excel格式的数据文件。它们都有很多选项,可以根据具体文件的格式进行设置。 二、查看数据 在pandas中,使用以下函数来查看数据: 1. head() - 显示数据框的前几行; 2. tail() - 显示数据框的后几行; 3. columns - 显示数据框的列名; 4. shape - 显示数据框的行列数; 5. info() - 显示数据框的基本信息,包括每列的名称、非空值数量和数据类型。 三、数据清洗 在数据清洗中,有以下一些常见的技术: 1. 删除重复行:使用drop_duplicates()函数; 2. 替换空值:使用fillna()函数; 3. 删除空值:使用dropna()函数; 4. 更改数据类型:使用astype()函数。 四、数据准备 在数据准备中,有以下一些常见的技术: 1. 数据合并:使用merge()函数; 2. 数据筛选:使用loc()函数或者iloc()函数; 3. 数据分组:使用groupby()函数; 4. 数据排序:使用sort_values()函数。 五、数据分析 在数据分析中,有以下一些常见的技术: 1. 数据聚合:使用agg()函数; 2. 统计描述:使用describe()函数; 3. 数据可视化:使用matplotlib或者seaborn库。 综上所述,pandas预处理是数据分析中必不可少的一步。通过使用pandas提供的函数和方法,可以方便地清理和处理数据,使其更容易被分析。 ### 回答3: PandasPython中最强大的数据处理库之一,它提供了DataFrame和Series这两种数据结构,可以快速便捷地处理数据。在数据分析过程中,我们往往需要先对数据进行预处理,以便后续的分析。Pandas提供了一系列的方法和函数,可以帮助我们进行数据的预处理。 首先,在进行数据分析之前,我们需要了解自己所面对的数据类型和数据结构。Pandas中的DataFrame结构就是类似于表格的结构,每一行代表一个样本,每一列代表一个属性。Series则是一维的数组结构。通过pandas.read_csv(),我们可以读取CSV格式的数据,并转化为DataFrame结构。 接下来,我们要对数据进行一些基本的处理,例如数据清洗、数据去重、缺失值处理、异常值处理等。在数据清洗过程中,我们往往需要对数据进行一些特殊的处理,例如字符串的分割、合并、替换等操作,Pandas提供了一系列能够对文本进行操作的函数。在数据去重方面,我们可以使用drop_duplicates()函数,它可以去除DataFrame中的重复记录。在处理缺失值时,Pandas提供了一系列的函数,如fillna()函数、dropna()函数,可以方便地将NaN值变为其他有意义的值,或者删除缺失值的行或列。在异常值处理方面,我们可以使用isoutlier()函数来找到数据中的异常值,并进行处理。 在数据预处理完成后,我们可以对数据进行一些统计分析,例如计算小计、计算总计、分位数、极差、方差、标准差等统计指标。我们可以使用describe()函数来获得数据的统计描述,还可以使用groupby()函数来对数据分组,使用agg()函数对每组进行计算统计指标。此外,我们还可以对数据进行排序、丢弃、合并等操作。 总之,Pandas是一个非常强大的Python库,可以轻松处理数据预处理和数据处理方面的任务。Pandas作为数据分析和数据处理的基础库,使用熟练后可以在数据分析中发挥更大的作用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

名本无名

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值