向 pandas 数据框中插入一行

2025-01-21 09:01:00
admin
原创
77
摘要:问题描述:我有一个数据框:s1 = pd.Series([5, 6, 7]) s2 = pd.Series([7, 8, 9]) df = pd.DataFrame([list(s1), list(s2)], columns = ["A", "B", "...

问题描述:

我有一个数据框:

s1 = pd.Series([5, 6, 7])
s2 = pd.Series([7, 8, 9])

df = pd.DataFrame([list(s1), list(s2)],  columns =  ["A", "B", "C"])

   A  B  C
0  5  6  7
1  7  8  9

[2 rows x 3 columns]

我需要添加第一行 [2, 3, 4] 来获得:

   A  B  C
0  2  3  4
1  5  6  7
2  7  8  9

我已经尝试过append()并实现了concat()这些功能,但找不到正确的方法。

如何向数据框添加/插入系列?


解决方案 1:

只需将行分配给特定索引,使用loc

 df.loc[-1] = [2, 3, 4]  # adding a row
 df.index = df.index + 1  # shifting index
 df = df.sort_index()  # sorting by index

您将获得所需的结果:

    A  B  C
 0  2  3  4
 1  5  6  7
 2  7  8  9

请参阅 Pandas 文档索引:放大设置。

解决方案 2:

测试几个答案后发现,pd.concat()对于大型数据框来说,使用更有效。

dict比较使用和的性能listlist效率更高,但对于小型数据框,使用dict应该没有问题,而且可读性更强。


第一名pd.concat() + list

%%timeit
df = pd.DataFrame(columns=['a', 'b'])
for i in range(10000):
    df = pd.concat([pd.DataFrame([[1,2]], columns=df.columns), df], ignore_index=True)

每循环4.88 秒± 47.1 毫秒(7 次运行的平均值 ± 标准差,每次 1 个循环)

第二 - pd.append() + dict[从v2.0.0开始删除]

%%timeit

df = pd.DataFrame(columns=['a', 'b'])
for i in range(10000):
    df = df.append({'a': 1, 'b': 2}, ignore_index=True)

每循环10.2 秒± 41.4 毫秒(7 次运行的平均值 ± 标准差,每次 1 个循环)

第三名pd.DataFrame().loc + index operations

%%timeit
df = pd.DataFrame(columns=['a','b'])
for i in range(10000):
    df.loc[-1] = [1,2]
    df.index = df.index + 1
    df = df.sort_index()

每循环17.5 秒± 37.3 毫秒(7 次运行的平均值 ± 标准差,每次 1 个循环)

解决方案 3:

不确定您是如何调用的concat(),但只要两个对象属于同一类型,它就应该有效。也许问题是您需要将第二个向量转换为数据框?使用您定义的 df 对我来说有效:

df2 = pd.DataFrame([[2,3,4]], columns=['A','B','C'])
pd.concat([df2, df])

解决方案 4:

实现此目的的一种方法是

>>> pd.DataFrame(np.array([[2, 3, 4]]), columns=['A', 'B', 'C']).append(df, ignore_index=True)
Out[330]: 
   A  B  C
0  2  3  4
1  5  6  7
2  7  8  9

通常,最简单的方法是附加数据框,而不是系列。对于您的情况,由于您希望新行位于“顶部”(具有起始 ID),并且没有函数pd.prepend(),因此我首先创建新的数据框,然后附加旧数据框。

ignore_index将忽略数据框中旧的正在进行的索引,并确保第一行实际上以索引开头,1而不是以索引重新开始0

典型免责声明:Cetero censeo ... 附加行是一种非常低效的操作。如果您关心性能并且可以以某种方式确保首先使用正确的(较长的)索引创建数据框,然后将附加行插入数据框,那么您绝对应该这样做。参见:

>>> index = np.array([0, 1, 2])
>>> df2 = pd.DataFrame(columns=['A', 'B', 'C'], index=index)
>>> df2.loc[0:1] = [list(s1), list(s2)]
>>> df2
Out[336]: 
     A    B    C
0    5    6    7
1    7    8    9
2  NaN  NaN  NaN
>>> df2 = pd.DataFrame(columns=['A', 'B', 'C'], index=index)
>>> df2.loc[1:] = [list(s1), list(s2)]

到目前为止,我们拥有的是df

>>> df2
Out[339]: 
     A    B    C
0  NaN  NaN  NaN
1    5    6    7
2    7    8    9

但现在您可以像下面这样轻松插入行。由于空间已预先分配,因此这样做更加高效。

>>> df2.loc[0] = np.array([2, 3, 4])
>>> df2
Out[341]: 
   A  B  C
0  2  3  4
1  5  6  7
2  7  8  9

解决方案 5:

我整理了一个简短的函数,使得插入行时更加灵活:

def insert_row(idx, df, df_insert):
    dfA = df.iloc[:idx, ]
    dfB = df.iloc[idx:, ]

    df = dfA.append(df_insert).append(dfB).reset_index(drop = True)

    return df

可以进一步缩写为:

def insert_row(idx, df, df_insert):
    return df.iloc[:idx, ].append(df_insert).append(df.iloc[idx:, ]).reset_index(drop = True)

然后你可以使用类似的东西:

df = insert_row(2, df, df_new)

您想要插入的2索引位置在哪里。df`df_new`

解决方案 6:

我们可以使用numpy.insert。这样做的好处是灵活。你只需要指定要插入到的索引即可。

s1 = pd.Series([5, 6, 7])
s2 = pd.Series([7, 8, 9])

df = pd.DataFrame([list(s1), list(s2)],  columns =  ["A", "B", "C"])

pd.DataFrame(np.insert(df.values, 0, values=[2, 3, 4], axis=0), columns=df.columns)

    0   1   2
0   2   3   4
1   5   6   7
2   7   8   9

对于np.insert(df.values, 0, values=[2, 3, 4], axis=0),0 告诉函数您想要放置新值的位置/索引。

解决方案 7:

在 pandas 中添加一行非常简单DataFrame

  1. 创建一个常规 Python 字典,其列名与您的相同Dataframe

  2. 使用pandas.append()方法并传入你的字典名称,其中.append()是 DataFrame 实例上的方法;

  3. ignore_index=True在词典名称后立即添加。

解决方案 8:

这可能看起来过于简单,但令人难以置信的是,一个简单的插入新行功能没有内置。我已经阅读了很多关于将新的 df 附加到原始内容的文章,但我想知道这是否会更快。

df.loc[0] = [row1data, blah...]
i = len(df) + 1
df.loc[i] = [row2data, blah...]

解决方案 9:

以下是在不进行排序和重新设置索引的情况下将行插入到 pandas 数据框中的最佳方法:

import pandas as pd

df = pd.DataFrame(columns=['a','b','c'])

def insert(df, row):
    insert_loc = df.index.max()

    if pd.isna(insert_loc):
        df.loc[0] = row
    else:
        df.loc[insert_loc + 1] = row

insert(df,[2,3,4])
insert(df,[8,9,0])
print(df)

解决方案 10:

创建具有列名的空 df:

df = pd.DataFrame(columns = ["A", "B", "C"])

插入新行:

df.loc[len(df.index)] = [2, 3, 4]
df.loc[len(df.index)] = [5, 6, 7]
df.loc[len(df.index)] = [7, 8, 9]

解决方案 11:

concat()似乎比最后一行插入和重新索引要快一点。如果有人想知道两种顶级方法的速度:

In [x]: %%timeit
     ...: df = pd.DataFrame(columns=['a','b'])
     ...: for i in range(10000):
     ...:     df.loc[-1] = [1,2]
     ...:     df.index = df.index + 1
     ...:     df = df.sort_index()

每循环 17.1 秒 ± 705 毫秒(7 次运行的平均值 ± 标准差,每次 1 个循环)

In [y]: %%timeit
     ...: df = pd.DataFrame(columns=['a', 'b'])
     ...: for i in range(10000):
     ...:     df = pd.concat([pd.DataFrame([[1,2]], columns=df.columns), df])

每循环6.53秒 ± 127 毫秒(7 次运行的平均值 ± 标准差,每次 1 个循环)

解决方案 12:

我突然想到,也许T 属性是一个有效的选择。Transpose可以摆脱 @flow2k 提到的有些误导df.loc[-1] = [2, 3, 4]并且它适用于更通用的情况,例如您想要 [2, 3, 4]在任意行之前插入,这对于 来说很难concat()实现append()。而且没有必要费心定义和调试函数。

a = df.T
a.insert(0,'anyName',value=[2,3,4])
# just give insert() any column name you want, we'll rename it.
a.rename(columns=dict(zip(a.columns,[i for i in range(a.shape[1])])),inplace=True)
# set inplace to a Boolean as you need.
df=a.T
df

    A   B   C
0   2   3   4
1   5   6   7
2   7   8   9

我想这可以部分解释@MattCochrane 关于为什么 pandas 没有像 insert() 那样插入行的方法的抱怨。

解决方案 13:

对于那些想要从前一个数据框中连接一行的人,请使用双括号([[...]]iloc

s1 = pd.Series([5, 6, 7])
s2 = pd.Series([7, 8, 9])

df = pd.DataFrame([list(s1), list(s2)],  columns =  ["A", "B", "C"])

#   A   B   C
# 0 5   6   7
# 1 7   8   9

pd.concat((df.iloc[[0]],  # [[...]] used to slice DataFrame as DataFrame
           df), ignore_index=True)

#   A   B   C
# 0 5   6   7
# 1 5   6   7
# 2 7   8   9

如需复制或复制任意次数,请与星号结合使用。

pd.concat((df.iloc[[0]],
           df,
           *[df.iloc[[1]]] * 4), ignore_index=True)

#   A   B   C
# 0 5   6   7
# 1 7   8   9
# 2 7   8   9
# 3 7   8   9
# 4 7   8   9

解决方案 14:

假设索引是一个默认索引,其整数值从 0 开始:

import pandas as pd

data = [[5, 6, 7], [7, 8, 9]]
df = pd.DataFrame(data, columns=list('ABC'))
row = [2, 3, 4]

# Inset new row
df.loc[-1] = row
df = df.sort_index()
df.index = range(len(df))

print(df)

调整df.loc[-1]原始索引中的任意位置。

   A  B  C
0  2  3  4
1  5  6  7
2  7  8  9

解决方案 15:

您可以简单地将行附加到 DataFrame 的末尾,然后调整索引。

例如:

df = df.append(pd.DataFrame([[2,3,4]],columns=df.columns),ignore_index=True)
df.index = (df.index + 1) % len(df)
df = df.sort_index()

或者使用concat如下方式:

df = pd.concat([pd.DataFrame([[1,2,3,4,5,6]],columns=df.columns),df],ignore_index=True)

解决方案 16:

按照下面的例子操作:

a_row = pd.Series([1, 2])

df = pd.DataFrame([[3, 4], [5, 6]])

row_df = pd.DataFrame([a_row])

df = pd.concat([row_df, df], ignore_index=True)

结果是:

   0  1
0  1  2
1  3  4
2  5  6

解决方案 17:

s1 = pd.Series([5, 6, 7])
s2 = pd.Series([7, 8, 9])

df = pd.DataFrame([list(s1), list(s2)],  columns =  ["A", "B", "C"])

要在任意位置插入新行,您可以指定行位置:row_pos = -1 表示插入在顶部,或者 row_pos = 0.5 表示插入在第 0 行和第 1 行之间。

row_pos = -1
insert_row = [2,3,4]

df.loc[row_pos] = insert_row
df = df.sort_index()
df = df.reset_index(drop = True)

row_pos = -1

The outcome is:

    A   B   C
0   2   3   4
1   5   6   7
2   7   8   9

row_pos = 0.5

The outcome is:

    A   B   C
0   5   6   7
1   2   3   4
2   7   8   9

解决方案 18:

鉴于 pandas 的数据框的数据结构是一系列系列(每个系列是一列),因此可以方便地在任何位置插入一列。所以我想到的一个想法是先转置你的数据框,插入一列,然后再转置回去。你可能还需要重命名索引(行名),如下所示:

s1 = pd.Series([5, 6, 7])
s2 = pd.Series([7, 8, 9])

df = pd.DataFrame([list(s1), list(s2)],  columns =  ["A", "B", "C"])
df = df.transpose()
df.insert(0, 2, [2,3,4])
df = df.transpose()
df.index = [i for i in range(3)]
df

    A   B   C
0   2   3   4
1   5   6   7
2   7   8   9

解决方案 19:

在 Pandas 数据框中添加一行的最简单方法是:

DataFrame.loc[ location of insertion ]= list( )

例子 :

DF.loc[ 9 ] = [ ´Pepe’ , 33, ´Japan’ ]

注意:列表的长度应该与数据框的长度相匹配。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用