python pandas 数据框:将函数 return 元组分配给数据框的两列
python pandas data frame: assign function return tuple to two columns of a data frame
我想使用返回 tuple
的函数将两列添加到 pandas Dataframe
:
data=pd.DataFrame({'a':[1,2,3,4,5,6],'b':['ssdfsdf','bbbbbb','cccccccccccc','ddd','eeeeee','ffffff']})
def givetup(string):
result1 = string[0:3]
# please imagine here a bunch of string functions concatenated.
# including nlp methods with SpaCy
result2 = result1.upper()
# the same here, imagine a bunch of steps to calculate result2 based on result 1
return (result1,result2)
data['c'] = data['b'].apply(lambda x: givetup(x)[0])
data['d'] = data['b'].apply(lambda x: givetup(x)[1])
这是非常低效的(我正在处理数百万行),因为我调用了同一个函数两次并进行了两次计算。
由于 result2
依赖于 result 1
我最好不要将 givetup
分成两个函数
我如何一次性将 result1
和 result2
分配到新列 c 和 d 中,只需调用一次功能?
最有效的方法是什么?
请记住 result1
和 result2
是非常耗时的字符串计算。
编辑 1:
我知道这个:
Apply pandas function to column to create multiple new columns?
即应用向量化函数。在我的特殊情况下,这是非常不受欢迎的,甚至可能是不可能的。假设结果1和结果2是基于语言模型计算的,我需要纯文本。
您可以在此处尝试列表理解:
data[['c','d']] = [givetup(a) for a in data['b']]
输出:
a b c d
0 1 ssdfsdf ssd SSD
1 2 bbbbbb bbb BBB
2 3 cccccccccccc ccc CCC
3 4 ddd ddd DDD
4 5 eeeeee eee EEE
5 6 ffffff fff FFF
zip
/map
data['c'], data['d'] = zip(*map(givetup, data['b']))
data
a b c d
0 1 ssdfsdf ssd SSD
1 2 bbbbbb bbb BBB
2 3 cccccccccccc ccc CCC
3 4 ddd ddd DDD
4 5 eeeeee eee EEE
5 6 ffffff fff FFF
Series.str
和 assign
这特定于 givetup
中给出的示例。但如果可以解开,那么它可能是值得的。
assign
方法参数可以采用引用在参数中创建的列的可扩展性(NEAT)。
data.assign(c=lambda d: d.b.str[0:3], d=lambda d: d.c.str.upper())
a b c d
0 1 ssdfsdf ssd SSD
1 2 bbbbbb bbb BBB
2 3 cccccccccccc ccc CCC
3 4 ddd ddd DDD
4 5 eeeeee eee EEE
5 6 ffffff fff FFF
时间
data = pd.concat([data] * 10_000, ignore_index=True)
%timeit data['c'], data['d'] = zip(*map(givetup, data['b']))
%timeit data[['c','d']] = [givetup(a) for a in data['b']]
%timeit data.assign(c=lambda d: d.b.str[0:3], d=lambda d: d.c.str.upper())
69.7 ms ± 865 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
137 ms ± 937 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
34.6 ms ± 235 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
另一种方法是对系列使用应用函数:
import pandas as pd
data=pd.DataFrame({'a':[1,2,3,4,5,6],'b':['ssdfsdf','bbbbbb','cccccccccccc','ddd','eeeeee','ffffff']})
def givetup(column):
column1 = column[0:3]
column2 = column[0:3].upper()
return pd.Series([column1, column2])
data[['c','d']] = data['b'].apply(lambda x: givetup(x))
我想使用返回 tuple
的函数将两列添加到 pandas Dataframe
:
data=pd.DataFrame({'a':[1,2,3,4,5,6],'b':['ssdfsdf','bbbbbb','cccccccccccc','ddd','eeeeee','ffffff']})
def givetup(string):
result1 = string[0:3]
# please imagine here a bunch of string functions concatenated.
# including nlp methods with SpaCy
result2 = result1.upper()
# the same here, imagine a bunch of steps to calculate result2 based on result 1
return (result1,result2)
data['c'] = data['b'].apply(lambda x: givetup(x)[0])
data['d'] = data['b'].apply(lambda x: givetup(x)[1])
这是非常低效的(我正在处理数百万行),因为我调用了同一个函数两次并进行了两次计算。
由于 result2
依赖于 result 1
我最好不要将 givetup
分成两个函数
我如何一次性将 result1
和 result2
分配到新列 c 和 d 中,只需调用一次功能?
最有效的方法是什么?
请记住 result1
和 result2
是非常耗时的字符串计算。
编辑 1: 我知道这个: Apply pandas function to column to create multiple new columns?
即应用向量化函数。在我的特殊情况下,这是非常不受欢迎的,甚至可能是不可能的。假设结果1和结果2是基于语言模型计算的,我需要纯文本。
您可以在此处尝试列表理解:
data[['c','d']] = [givetup(a) for a in data['b']]
输出:
a b c d
0 1 ssdfsdf ssd SSD
1 2 bbbbbb bbb BBB
2 3 cccccccccccc ccc CCC
3 4 ddd ddd DDD
4 5 eeeeee eee EEE
5 6 ffffff fff FFF
zip
/map
data['c'], data['d'] = zip(*map(givetup, data['b']))
data
a b c d
0 1 ssdfsdf ssd SSD
1 2 bbbbbb bbb BBB
2 3 cccccccccccc ccc CCC
3 4 ddd ddd DDD
4 5 eeeeee eee EEE
5 6 ffffff fff FFF
Series.str
和 assign
这特定于 givetup
中给出的示例。但如果可以解开,那么它可能是值得的。
assign
方法参数可以采用引用在参数中创建的列的可扩展性(NEAT)。
data.assign(c=lambda d: d.b.str[0:3], d=lambda d: d.c.str.upper())
a b c d
0 1 ssdfsdf ssd SSD
1 2 bbbbbb bbb BBB
2 3 cccccccccccc ccc CCC
3 4 ddd ddd DDD
4 5 eeeeee eee EEE
5 6 ffffff fff FFF
时间
data = pd.concat([data] * 10_000, ignore_index=True)
%timeit data['c'], data['d'] = zip(*map(givetup, data['b']))
%timeit data[['c','d']] = [givetup(a) for a in data['b']]
%timeit data.assign(c=lambda d: d.b.str[0:3], d=lambda d: d.c.str.upper())
69.7 ms ± 865 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
137 ms ± 937 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
34.6 ms ± 235 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
另一种方法是对系列使用应用函数:
import pandas as pd
data=pd.DataFrame({'a':[1,2,3,4,5,6],'b':['ssdfsdf','bbbbbb','cccccccccccc','ddd','eeeeee','ffffff']})
def givetup(column):
column1 = column[0:3]
column2 = column[0:3].upper()
return pd.Series([column1, column2])
data[['c','d']] = data['b'].apply(lambda x: givetup(x))