Python 在数据框中插入一行
我有一个数据帧:Python 在数据框中插入一行,python,pandas,dataframe,insert,Python,Pandas,Dataframe,Insert,我有一个数据帧: 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
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()
函数,但找不到正确的方法
如何向数据帧添加/插入序列?实现此目的的一种方法是
>>> 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
将忽略数据帧中旧的正在进行的索引,并确保第一行实际上以index1
开始,而不是以index0
重新启动
典型免责声明:Cetero censeo。。。追加行是一种效率很低的操作。如果您关心性能,并且能够以某种方式确保首先创建具有正确(更长)索引的数据帧,然后将额外的行插入到数据帧中,那么您肯定应该这样做。见:
到目前为止,我们拥有您所拥有的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
将行分配给特定索引即可:
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
中的索引位置,您要在其中插入df\u new
,我们可以使用。这具有灵活性的优点。您只需要指定要插入的索引
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告诉函数要放置新值的位置/索引。下面是在不排序和重置索引的情况下将行插入数据帧的最佳方法:
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的内容,但是我想知道这是否会更快
df.loc[0] = [row1data, blah...]
i = len(df) + 1
df.loc[i] = [row2data, blah...]
您可以简单地将行附加到数据帧的末尾,然后调整索引 例如:
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],忽略_index=True)
将一行添加到数据帧中非常简单:
Dataframe
相同
pandas.append()
方法并传入字典的名称,其中.append()
是数据帧实例上的方法
ignore\u index=True
添加到词典名称后面
在数据框中添加行的最简单方法是:
DataFrame.loc[插入位置]=列表()
例如:
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次)
6.53s±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.append()
对于大型数据帧更有效
比较使用dict
和list
的性能,list
效率更高,但对于小数据帧,使用dict
应该没有问题,可读性更强
第一个-
pd.append()+列表
4.88 s±47.1 ms/圈(7次运行的平均值±标准偏差,每个循环1次)
第二个-pd.append()+dict
10.2 s±41.4 ms/圈(7次运行的平均值±标准偏差,每个循环1次)
第三个-pd.DataFrame().loc+索引操作
17.5秒每个循环±37.3毫秒(平均±标准偏差7次运行,每个循环1次)这是一个很好的解决方案,我试图将系列插入数据帧。现在对我来说已经足够好了。我最喜欢最后一个选择。这确实符合我真正想做的。谢谢@FooBar!如果您不想设置放大,但要在数据帧内插入,请查看移位索引选项:df.sort().reset_index(drop=True)df.sort不推荐使用,请使用df.sort_index()@Piotr-这非常有效,但是当您想从数据帧复制行时会发生什么情况,例如df.loc[-1]=df.iloc[[0]
,然后插入那个?框架中添加了一个索引列,给出
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])
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
%%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)
%%timeit
df = pd.DataFrame(columns=['a', 'b'])
for i in range(10000):
df = df.append({'a': 1, 'b': 2}, ignore_index=True)
%%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()