如何在 Pandas 数据帧切片中使用应用来设置多列的值

How to use apply in a Pandas dataframe slice to set values of multiple columns

我正在尝试使用 apply 函数通过 .loc 查询将新值分配给数据帧切片中的两个现有列。

要重现 - 首先创建一个数据框:

import re
import panads as pd
data = [[1000, "MSL", "Test string"], [2000, 'AGL', 'other string'], [0, 'AGL', "xxxx SFC-10000ft MSLXXX"]]
df = pd.DataFrame(data=data, columns=['Alt', "AltType",'FreeText'])

然后创建应用函数

def testapply(row):
    try:
        match = re.findall("SFC-([0-9]+)FT (MSL|AGL|FL)", row.FreeText)[0]
        return (int(match[0]), match[1])
    except:
        return (0, row.AltType)

当我运行

df.loc[df['Alt']==0, ['Alt', 'AltType']] = df.loc[df['Alt']==0].apply(testapply, axis=1)

我想得到的结果是:

     Alt AltType                 FreeText
0   1000     MSL              Test string
1   2000     AGL             other string
2  10000     MSL  xxxx SFC-10000ft MSLXXX

但我最终得到的是:

            Alt       AltType                 FreeText
0          1000           MSL              Test string
1          2000           AGL             other string
2  (10000, MSL)  (10000, MSL)  xxxx SFC-10000FT MSLXXX

有谁知道如何一举完成这项工作?

只需添加tolist()

df.loc[df['Alt']==0, ['Alt', 'AltType']] = df.loc[df['Alt']==0].apply(testapply, axis=1).tolist()

让我们尝试 Series.str.extract 并使用带有 loc 的布尔索引来替换列 AltAltType 中的值,其中列 Alt 包含 0:

m = df['Alt'].eq(0)
df.loc[m, ['Alt', 'AltType']] = df.loc[m, 'FreeText'].str.extract(r'(?i)SFC-(\d+)FT\s(MSL|AGL|FL)').values

     Alt AltType                 FreeText
0   1000     MSL              Test string
1   2000     AGL             other string
2  10000     MSL  xxxx SFC-10000ft MSLXXX

仅将您的 testapply 函数更改为:

def testapply(row):
    try:
        match = re.findall("SFC-([0-9]+)ft (MSL|AGL|FL)", row.FreeText)[0]
        print(match)
        return (int(match[0]), match[1]).tolist()
    except:
        return (0, row.AltType)

对 select 相关的 Alt 列使用 loc 访问器。通过使用 regex

从匹配的 FreeText 中提取 digit 来计算值
df.loc[df['Alt']==0,'Alt']=df.loc[df['Alt']==0,'FreeText'].str.extract('(\d+)')[0]



     Alt AltType                 FreeText
0   1000     MSL              Test string
1   2000     AGL             other string
2  10000     AGL  xxxx SFC-10000ft MSLXXX