Pandas 使用应用函数在数据框中输出 2 列,returns 一个包含 2 个项目的元组/列表
Pandas output 2 column in data frame using apply function which returns a tuple / list of 2 items
我有一个包含 10 列的数据框。您可以使用此代码生成名为 df
.
的示例框架
cols = []
for i in range(1,11):
cols.append(f'x{i}')
df = pd.DataFrame(np.random.randint(10,99,size=(10, 10)), columns=cols)
数据框看起来像这样,它是随机生成的,所以你的数字会有所不同。
x1 x2 x3 x4 x5 x6 x7 x8 x9 x10
0 91 30 82 10 92 62 43 66 96 88
1 61 95 77 16 19 67 88 44 72 52
2 44 21 68 93 29 40 25 78 96 94
3 80 11 50 55 14 56 21 78 36 41
4 84 52 97 29 92 44 89 78 27 62
5 11 82 83 84 34 90 56 74 68 76
6 31 92 13 89 95 80 75 59 81 74
7 14 25 47 98 67 18 78 10 64 40
8 52 75 60 44 36 18 33 79 65 18
9 19 69 12 61 60 92 61 21 43 72
我想应用一个 return 元组的函数。我想使用元组在我的数据框中创建 2 列。
def some_func(i1,i2):
o1 = i2 / i1 * 0.5
o2 = i2 * o1 * 6
return o1,o2
当我这样做时,
df['c1'], df['c2'] = df.apply(lambda row: some_func(row['x9'],row['x10']), axis=1)
我收到这个错误,
ValueError: too many values to unpack (expected 2)
输出应该是这样的,
x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 c1 c2
0 91 30 82 10 92 62 43 66 96 88 0.458333 242.000000
1 61 95 77 16 19 67 88 44 72 52 0.361111 112.666667
2 44 21 68 93 29 40 25 78 96 94 0.489583 276.125000
3 80 11 50 55 14 56 21 78 36 41 0.569444 140.083333
4 84 52 97 29 92 44 89 78 27 62 1.148148 427.111111
5 11 82 83 84 34 90 56 74 68 76 0.558824 254.823529
6 31 92 13 89 95 80 75 59 81 74 0.456790 202.814815
7 14 25 47 98 67 18 78 10 64 40 0.312500 75.000000
8 52 75 60 44 36 18 33 79 65 18 0.138462 14.953846
9 19 69 12 61 60 92 61 21 43 72 0.837209 361.674419
如果我只 return 1 输出,并创建 1 列,它工作正常。如何输出 2 个项目(元组或 2 个项目的列表)并使用它创建 2 个新列?
一定有几种方法。
我试着做你想要的,只做了一些改变。
- 没有
lambda
用法,因为您已经定义了自己的函数。
result_type="expand"
在 apply()
中,以便 return 值将拆分为多个列。
Dataframe
而不是两个 Series
以便 return 值可以拆分到数据帧中(由两个 Series
组成)。
import pandas as pd
df = pd.DataFrame({
'inputcol1': [1, 2, 3, 4],
'inputcol2': [1, 2, 3, 4]
})
def some_func(x):
output1 = x['inputcol1'] + x['inputcol2']
output2 = x['inputcol2'] - x['inputcol2']
return output1, output2
print(df)
# inputcol1 inputcol2
#0 1 1
#1 2 2
#2 3 3
#3 4 4
df[['outputcol1', 'outputcol2']] = df[['inputcol1', 'inputcol2']].apply(some_func, axis=1, result_type="expand")
print(df)
# inputcol1 inputcol2 outputcol1 outputcol2
#0 1 1 2 0
#1 2 2 4 0
#2 3 3 6 0
#3 4 4 8 0
首先生成一个临时DataFrame:
wrk = df.apply(lambda row: some_func(row['x9'],row['x10']), axis=1)\
.apply(pd.Series, index=['c1', 'c2'])
详情:
df.apply(…)
- 您的代码 - 从每一行元组创建它们
收集在 系列.
apply(pd.Series, index=['c1', 'c2'])
- 来自 Series 的每个元素
到目前为止生成的(一个元组)创建一个 Series 索引包含
新的列名。然后将这些 Series 对象收集到 DataFrame 中,
其中源索引值现在是列名。
打印wrk以查看目前生成的结果。
然后加入df并将结果保存回df:
df = df.join(wrk)
由于您需要逐行遍历多列,因此更好/更有效的方法是使用 zip
+ for 循环创建一个元组列表,您可以直接将其分配给列列表原始数据框:
df[['c1', 'c2']] = [some_func(x, y) for x, y in zip(df.x9, df.x10)]
df
x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 c1 c2
0 20 67 76 95 28 60 82 81 90 93 0.516667 288.300000
1 94 30 97 82 51 10 54 43 36 41 0.569444 140.083333
2 50 57 85 48 67 65 41 91 48 46 0.479167 132.250000
3 61 36 44 59 18 71 42 18 56 77 0.687500 317.625000
4 11 85 34 66 45 55 21 42 77 27 0.175325 28.402597
5 20 19 86 46 97 21 84 12 86 98 0.569767 335.023256
6 24 87 65 62 22 43 26 80 15 64 2.133333 819.200000
7 38 15 23 22 89 89 19 32 21 33 0.785714 155.571429
8 82 88 64 89 92 88 15 30 85 83 0.488235 243.141176
9 96 24 91 70 96 54 57 81 59 32 0.271186 52.067797
我有一个包含 10 列的数据框。您可以使用此代码生成名为 df
.
cols = []
for i in range(1,11):
cols.append(f'x{i}')
df = pd.DataFrame(np.random.randint(10,99,size=(10, 10)), columns=cols)
数据框看起来像这样,它是随机生成的,所以你的数字会有所不同。
x1 x2 x3 x4 x5 x6 x7 x8 x9 x10
0 91 30 82 10 92 62 43 66 96 88
1 61 95 77 16 19 67 88 44 72 52
2 44 21 68 93 29 40 25 78 96 94
3 80 11 50 55 14 56 21 78 36 41
4 84 52 97 29 92 44 89 78 27 62
5 11 82 83 84 34 90 56 74 68 76
6 31 92 13 89 95 80 75 59 81 74
7 14 25 47 98 67 18 78 10 64 40
8 52 75 60 44 36 18 33 79 65 18
9 19 69 12 61 60 92 61 21 43 72
我想应用一个 return 元组的函数。我想使用元组在我的数据框中创建 2 列。
def some_func(i1,i2):
o1 = i2 / i1 * 0.5
o2 = i2 * o1 * 6
return o1,o2
当我这样做时,
df['c1'], df['c2'] = df.apply(lambda row: some_func(row['x9'],row['x10']), axis=1)
我收到这个错误,
ValueError: too many values to unpack (expected 2)
输出应该是这样的,
x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 c1 c2
0 91 30 82 10 92 62 43 66 96 88 0.458333 242.000000
1 61 95 77 16 19 67 88 44 72 52 0.361111 112.666667
2 44 21 68 93 29 40 25 78 96 94 0.489583 276.125000
3 80 11 50 55 14 56 21 78 36 41 0.569444 140.083333
4 84 52 97 29 92 44 89 78 27 62 1.148148 427.111111
5 11 82 83 84 34 90 56 74 68 76 0.558824 254.823529
6 31 92 13 89 95 80 75 59 81 74 0.456790 202.814815
7 14 25 47 98 67 18 78 10 64 40 0.312500 75.000000
8 52 75 60 44 36 18 33 79 65 18 0.138462 14.953846
9 19 69 12 61 60 92 61 21 43 72 0.837209 361.674419
如果我只 return 1 输出,并创建 1 列,它工作正常。如何输出 2 个项目(元组或 2 个项目的列表)并使用它创建 2 个新列?
一定有几种方法。
我试着做你想要的,只做了一些改变。
- 没有
lambda
用法,因为您已经定义了自己的函数。 result_type="expand"
在apply()
中,以便 return 值将拆分为多个列。Dataframe
而不是两个Series
以便 return 值可以拆分到数据帧中(由两个Series
组成)。
import pandas as pd
df = pd.DataFrame({
'inputcol1': [1, 2, 3, 4],
'inputcol2': [1, 2, 3, 4]
})
def some_func(x):
output1 = x['inputcol1'] + x['inputcol2']
output2 = x['inputcol2'] - x['inputcol2']
return output1, output2
print(df)
# inputcol1 inputcol2
#0 1 1
#1 2 2
#2 3 3
#3 4 4
df[['outputcol1', 'outputcol2']] = df[['inputcol1', 'inputcol2']].apply(some_func, axis=1, result_type="expand")
print(df)
# inputcol1 inputcol2 outputcol1 outputcol2
#0 1 1 2 0
#1 2 2 4 0
#2 3 3 6 0
#3 4 4 8 0
首先生成一个临时DataFrame:
wrk = df.apply(lambda row: some_func(row['x9'],row['x10']), axis=1)\
.apply(pd.Series, index=['c1', 'c2'])
详情:
df.apply(…)
- 您的代码 - 从每一行元组创建它们 收集在 系列.apply(pd.Series, index=['c1', 'c2'])
- 来自 Series 的每个元素 到目前为止生成的(一个元组)创建一个 Series 索引包含 新的列名。然后将这些 Series 对象收集到 DataFrame 中, 其中源索引值现在是列名。
打印wrk以查看目前生成的结果。
然后加入df并将结果保存回df:
df = df.join(wrk)
由于您需要逐行遍历多列,因此更好/更有效的方法是使用 zip
+ for 循环创建一个元组列表,您可以直接将其分配给列列表原始数据框:
df[['c1', 'c2']] = [some_func(x, y) for x, y in zip(df.x9, df.x10)]
df
x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 c1 c2
0 20 67 76 95 28 60 82 81 90 93 0.516667 288.300000
1 94 30 97 82 51 10 54 43 36 41 0.569444 140.083333
2 50 57 85 48 67 65 41 91 48 46 0.479167 132.250000
3 61 36 44 59 18 71 42 18 56 77 0.687500 317.625000
4 11 85 34 66 45 55 21 42 77 27 0.175325 28.402597
5 20 19 86 46 97 21 84 12 86 98 0.569767 335.023256
6 24 87 65 62 22 43 26 80 15 64 2.133333 819.200000
7 38 15 23 22 89 89 19 32 21 33 0.785714 155.571429
8 82 88 64 89 92 88 15 30 85 83 0.488235 243.141176
9 96 24 91 70 96 54 57 81 59 32 0.271186 52.067797