熊猫存储数据帧时,应用方法返回多行



>假设我有一个数据帧作为:

a=pd.DataFrame({'number':[1,2,3,4,5],'name':['A','B','C','D','E']})

我希望输出为:

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']})

这是一个简单的例子,我想要实现的是将第一个数据帧的每一行上的应用函数运行到某个函数(比如func1(,它将返回2行。此外,我需要将所有返回的行连接到单个数据帧中。

您可以返回 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使用矢量化方法满足我们的大多数需求,这些方法要快得多。应用基本上只是一个引擎盖下的 for 循环。

在这种情况下,将pd.concatSeries.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 函数的一种方法 - 对于每一行我们输出一个数据帧 - 使用 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

最新更新