[英]Pandas Store DataFrame when multiple rows are returned by Apply method
假设我有一个 DataFrame 为:
a=pd.DataFrame({'number':[1,2,3,4,5],'name':['A','B','C','D','E']})
我想要 output 为:
b=pd.DataFrame({'number':[1,1,2,4,3,9,4,16,5,25],'name':['A','A','B','B','C','C','D','D','E','E']})
这是一个简单的例子,我想要实现的是在第一个 DataFrame 的每一行上运行Apply function 到某个函数(比如 func1),它将返回 2 行。 我还需要将所有返回的行合并到一个 Dataframe 中。
您可以返回 2 个元素的列表,然后执行.explode()
:
a.number = a.number.apply(lambda x: [x, x**2])
print( a.explode('number').reset_index(drop=True) )
印刷:
number name
0 1 A
1 1 A
2 2 B
3 4 B
4 3 C
5 9 C
6 4 D
7 16 D
8 5 E
9 25 E
你不需要apply
,你几乎不需要, pandas/numpy
使用矢量化方法足以满足我们的大部分需求,这些方法速度更快。 Apply 基本上只是一个底层的 for 循环。
在这种情况下,将pd.concat
与Series.pow
一起使用:
pd.concat([a, a.assign(number=a['number'].pow(2))]).sort_index()
number name
0 1 A
0 1 A
1 2 B
1 4 B
2 3 C
2 9 C
3 4 D
3 16 D
4 5 E
4 25 E
这是我们可以使用 apply function 的一种方法 - 对于每一行我们 output 和 DataFrame - 在使用 apply 之后,我们得到了一系列所需的数据帧。 感谢Hossein指出我们想使用 apply
def func(series):
result = series.copy()
result[0] = result[0] ** 2
return pd.concat([series, result], axis=1).T
b = pd.conact(a.apply(lambda row: func(row), axis=1).to_list())
例如,如果您的func1
可以独立应用于两列,您可以执行以下操作:
def func1(num):
if isinstance(num, int):
return num ** 2
elif isinstance(num, str):
return num
else:
raise Exception("Invalid data type")
b = pd.DataFrame()
for col in a.columns:
transformed_array = [func1(num) for num in a[col]]
b[col] = np.array(list(zip(a[col], transformed_array))).flatten()
如果你想做一些适用于两者的事情:
def func1(series):
return pd.Series([series[0] ** 2, series[1]])
results = []
for idx, row in a.iterrows():
results.append(row.reset_index(drop=True))
results.append(func1(row))
b = pd.concat(results, axis=1).T.reset_index(drop=True)
b.columns = a.columns
可能不是最有效的方法,但可以让您完全自定义应用于每列的功能。 如果列相互影响,则第二种方式可以轻松更改func1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.