插入一行到熊猫数据框架

我有一个数据框架:

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()函数,但找不到正确的方法如何做到这一点。

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

676627 次浏览

实现这一点的一种方法是

>>> 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

只需使用loc将row赋值给一个特定的索引:

 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文档索引:放大设置

不确定你是如何调用concat(),但它应该工作,只要两个对象是同一类型。也许问题是你需要将你的第二个向量转换为一个数据框架?使用df,你定义了以下工作为我:

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

我把一个简短的函数放在一起,在插入一行时允许更多的灵活性:

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_newdf中的索引位置。

我们可以使用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))


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告诉函数要放置新值的位置/索引。

下面是在不排序和重置索引的情况下将一行插入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)

这看起来可能过于简单,但令人难以置信的是,一个简单的插入新行函数没有内置。我读了很多关于追加一个新的df到原来的,但我想知道这是否会更快。

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

您可以简单地将行追加到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)

向pandas DataFrame中添加一行非常简单:

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

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

  3. 在你的字典名称后面添加ignore_index=True

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

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

例子:

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

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

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 s±705 ms(平均±标准值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 s±127 ms /循环(7次运行的平均值±标准值,每个循环1次)

我突然想到,也许T属性是一个有效的选择。转置可以摆脱@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()那样插入一行的方法。

测试了几个答案,很明显,使用pd.concat()对于大数据帧更有效。

比较使用dictlist的性能,list更有效,但对于小数据帧,使用dict应该没有问题,而且在某种程度上可读性更好。


1st - 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 ms /循环(平均±标准值7次运行,每个循环1次)

2nd - pd.append() + dict

%%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 ms /循环(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 ms /循环(7次运行的平均值±标准值,每个循环1次)

按照下面的例子做:

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

创建列名为空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]
给出pandas的dataframe的数据结构是一个序列的列表(每个序列为一列),方便在任意位置插入一列。 我想到的一个办法是先转置数据帧,插入一列,再转置回来。你可能还需要重命名索引(行名),像这样:

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
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

对于那些想要连接前一个数据帧的行,使用双括号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]],
df,ignore_index=True)


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

若要复制或复制任意时间,请与星号组合。

pd.concat((pd.concat((df.iloc[[0]],
df), ignore_index=True),
df.iloc[[0]],
*[df.iloc[[1]]] * 4),ignore_index=True)
#   A   B   C
# 0 5   6   7
# 1 5   6   7
# 2 7   8   9
# 3 5   6   7
# 4 7   8   9
# 5 7   8   9
# 6 7   8   9
# 7 7   8   9