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
将忽略数据帧中旧的正在进行的索引,并确保第一行实际上以index
1
开始,而不是以index
0
重新启动

典型免责声明: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)

将一行添加到数据帧中非常简单:

  • 创建一个常规Python字典,其列名称与您的
    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()