根据条件将记录拆分为两个记录并进行计算
如标题所示,假设我有以下的数据表
import pandas as pd
df = pd.DataFrame({'UID':['A','B','C','D'],'FlagVal':[0,100,50,90],'TrueVal':[1000,1000,1000,1000]})
ndf = df.loc[~df['FlagVal'].between(0,100,inclusive='neither')]
mdf = df.loc[df['FlagVal'].between(0,100,inclusive='neither')]
我想把记录分成两部分,其中 FlagVal 的值在 0 到 100 之间。也就是说,生成一个叫 mdf 的数据表,并进行一些计算 -
def split_record(row):
gtd = row.copy()
ungtd = row.copy()
gtd['UID'] = row['UID'] + '_T1'
gtd['Flag'] = 'Y'
ungtd['UID'] = row['UID'] + '_T2'
ungtd['Flag'] = ''
gtd['TrueVal'] = float(gtd['TrueVal'])*(float(gtd['FlagVal'])/100.0)
ungtd['TrueVal'] = float(ungtd['TrueVal'])*(1 - (float(ungtd['FlagVal'])/100.0))
gtd['FlagVal'] = 100
ungtd['FlagVal'] = 0
result_data = pd.DataFrame([gtd, ungtd])
return result_data
split_df = pd.concat([split_record(row) for _, row in mdf.iterrows()], ignore_index=True)
然后再和另一个叫 'ndf' 的数据表合并。对于大约1000条记录,这样做没问题,但当记录数量达到几百万时,就会变得很慢。我尝试使用 apply 函数,设置 axis=1,但不太确定如何再把结果和数据合并。
你能告诉我一个合适的函数来优化这个过程吗?
2 个回答
1
在编程中,有时候我们需要让程序在特定的条件下执行某些操作。比如说,当用户点击一个按钮时,我们希望程序能做出反应。这种情况就需要用到“事件处理”。
事件处理就是程序监听用户的操作,比如点击、输入等,然后根据这些操作来执行相应的代码。想象一下,你在玩一个游戏,按下某个键后,角色就会跳起来,这就是事件处理在起作用。
通常,我们会为每个事件设置一个“处理函数”,这个函数里写着当事件发生时要做的事情。比如,点击按钮后,可能会弹出一个消息框,告诉你“按钮被点击了”。
总之,事件处理让程序能够对用户的操作做出反应,从而使得程序更加互动和友好。
def split_record_df(df):
gtd = df.copy()
ungtd = df.copy()
gtd['UID'] = df['UID'] + '_T1'
gtd['Flag'] = 'Y'
ungtd['UID'] = df['UID'] + '_T2'
ungtd['Flag'] = ''
gtd['TrueVal'] = gtd['TrueVal']*(gtd['FlagVal']/100.0)
ungtd['TrueVal'] = ungtd['TrueVal']*(1 - (ungtd['FlagVal']/100.0))
gtd['FlagVal'] = 100
ungtd['FlagVal'] = 0
result_data = pd.concat([gtd, ungtd])
return result_data
split_df = split_record_df(df)
1
你可以用两个步骤来创建 split_df
(这样做会非常快):
# create the 100% part:
mdf_100 = pd.DataFrame({"TrueVal": mdf["FlagVal"].div(100) * mdf["TrueVal"]}).assign(
FlagVal=100, UID=mdf["UID"] + "_T1", Flag="Y"
)
# create the 0% part:
mdf_0 = pd.DataFrame(
{"TrueVal": (1 - mdf["FlagVal"].div(100)) * mdf["TrueVal"]}
).assign(FlagVal=0, UID=mdf["UID"] + "_T2", Flag="")
split_df = pd.concat([mdf_100, mdf_0]).sort_index()
print(split_df)
输出结果:
TrueVal FlagVal UID Flag
2 500.0 100 C_T1 Y
2 500.0 0 C_T2
3 900.0 100 D_T1 Y
3 100.0 0 D_T2
补充说明:如果有多个 TrueValX
列的话:
cols = ["TrueVal1", "TrueVal2", "TrueVal3"]
# create the 100% part:
mdf_100 = pd.DataFrame({c: mdf["FlagVal"].div(100) * mdf[c] for c in cols}).assign(
FlagVal=100, UID=mdf["UID"] + "_T1", Flag="Y"
)
# create the 0% part:
mdf_0 = pd.DataFrame({c: (1 - mdf["FlagVal"].div(100)) * mdf[c] for c in cols}).assign(
FlagVal=0, UID=mdf["UID"] + "_T2", Flag=""
)
split_df = pd.concat([mdf_100, mdf_0]).sort_index()
print(split_df)
输出结果:
TrueVal1 TrueVal2 TrueVal3 FlagVal UID Flag
2 500.0 1000.0 1500.0 100 C_T1 Y
2 500.0 1000.0 1500.0 0 C_T2
3 900.0 1800.0 2700.0 100 D_T1 Y
3 100.0 200.0 300.0 0 D_T2
输入的 df
:
UID FlagVal TrueVal1 TrueVal2 TrueVal3
0 A 0 1000 2000 3000
1 B 100 1000 2000 3000
2 C 50 1000 2000 3000
3 D 90 1000 2000 3000