首页 > 解决方案 > 在python中将变量复制到数据框中所有行的快速方法

问题描述

我有一个 500,000+ 行的大型数据框,其中仅包含“BASE”行上的 ID,所有后续“行”行都包含有关 ID 的信息。

我想将 ID 复制到每一行中,因此也有一种简单的方法来确定信息所属的 ID。

由于这是一个大型数据框,使用下面的代码简单地遍历行非常耗时,我运行了一个小时,它只通过数据框完成了 1/5。我会经常运行这个,因此需要一个更快的方法。

最终,我希望能够在 numpy 中使用矢量化来提供我所知道的使用 numpy.where() 的最快结果。当“IDinRow”变量 = TRUE 时,我尝试在函数中更新全局变量,但是,它只是为该全局变量创建了一个系列。我希望每次在 np.where 中调用函数时更新全局变量。但是,我不知道该怎么做。或者任何快速的方法

这就是我想要实现的

    0   1   2   IDInRow ID_Numpy
0   BASE    1234567 nan True    1234567
1   row 1   USD False   1234567
2   row 1   USD False   1234567
3   row Amount  USD False   1234567
4   row 1   USD False   1234567
5   row 1   USD False   1234567
6   row 1   USD False   1234567
7   BASE    7654321 nan True    7654321
8   row 1   EUR False   7654321
9   row 1   EUR False   7654321
10  row Amount  EUR False   7654321
11  row 1   EUR False   7654321

使用下面的代码,这就是我要实现的目标,我希望 ID_Numpy 等于 ID_Iterrow

    0   1   2   IDInRow ID  ID_Iterrow  ID_Numpy
0   BASE    1234567 nan True    1234567 1234567 1234567
1   row 1   USD False   1   1234567 1
2   row 1   USD False   1   1234567 1
3   row Amount  USD False   1   1234567 1
4   row 1   USD False   1   1234567 1
5   row 1   USD False   1   1234567 1
6   row 1   USD False   1   1234567 1
7   BASE    7654321 nan True    7654321 7654321 7654321
8   row 1   EUR False   1   7654321 1
9   row 1   EUR False   1   7654321 1
10  row Amount  EUR False   1   7654321 1
11  row 1   EUR False   1   7654321 1

import pandas as pd
import numpy as np

def IDLocator(ID):
        global strGlobalID
        strGlobalID = ID
        return strGlobalID

strSearch = 'BASE'

Data = {0:['BASE','row','row','row','row','row','row','BASE','row','row','row','row'],
        1:[1234567,1,1,'Amount',1,1,1,7654321,1,1,'Amount',1],
        2:['nan','USD','USD','USD','USD','USD','USD','nan','EUR','EUR','EUR','EUR']}

df = pd.DataFrame(Data)

#Creates Logic Around Delimiter In ID
df['IDInRow'] =  df[0].str.contains(strSearch)

#Adds the ID into the ID column
df['ID'] = np.where(df['IDInRow'] == True, df[1], 1)

#What I am trying to make work by using global variables and np.where
df['ID_Numpy'] = np.where(df['IDInRow'] == True, IDLocator(df['ID']), strGlobalID)

#Works But Very Slow
for index, row in df.iterrows():
    if df['ID'][index] != 1:
        strDealID = df['ID'][index] 
        df['ID'][index]  = strDealID
    else:
        df['ID'][index]  = strDealID

标签: pythonpython-3.xpandas

解决方案


df['newID'] = df.apply(lambda row: row[1] if row[0] == 'BASE' else np.nan, axis=1)
df['newID'] = df['newID'].fillna(method='ffill').astype(int)

推荐阅读