如何在 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
的布尔索引来替换列 Alt
和 AltType
中的值,其中列 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
我正在尝试使用 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
的布尔索引来替换列 Alt
和 AltType
中的值,其中列 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