无法在任何地方找到这个问题,所以请在此尝试:
我尝试做的基本上是使用groupby功能和自编函数来改变现有的DataFrame对象:
benchmark =
x y z field_1
1 1 3 a
1 2 5 b
9 2 4 a
1 2 5 c
4 6 1 c
我想要做的是分组field_1
,使用特定列作为输入应用函数,在这种情况下是列x
和y
,然后将结果添加回原始DataFrame benchmark
作为名为new_field
的新列。函数本身取决于field_1
中的值,即field_1=a
将产生与field_1=b
等相比的不同结果(因此分组开始)。
伪代码类似于:
1. grouped_data = benchmark.groupby(['field_1'])
2. apply own_function to grouped_data; with inputs ('x', 'y', grouped_data)
3. add back result from function to benchmark as column 'new_field'
谢谢,
benchmark =
x y z field_1
1 1 3 a
1 2 5 b
9 2 4 a
1 2 5 c
4 6 1 c
精化:
我还有一个DataFrame separate_data
,其中包含x
,
separate_data =
x a b c
1 1 3 7
2 2 5 6
3 2 4 4
4 2 5 9
5 6 1 10
需要插入现有的benchmark
DataFrame。 separate_data
中应该用于插值的哪一列取决于field_1
中的列benchmark
(即上面集(a,b,c)
中的值)。新列中的插值基于benchmark
中的x值。
结果:
benchmark =
x y z field_1 field_new
1 1 3 a interpolate using separate_data with x=1 and col=a
1 2 5 b interpolate using separate_data with x=1 and col=b
9 2 4 a ... etc
1 2 5 c ...
4 6 1 c ...
有道理吗?
答案 0 :(得分:3)
编辑:
我认为您需要先set_index
+ stack
重新设置separate_data
,然后按rename_axis
设置索引名称,并通过重命名设置Serie
的名称。
然后两个级别都可以groupby
并使用一些函数。
然后join
将apply
改为benchmark
,默认左连接:
separate_data1 =separate_data.set_index('x').stack().rename_axis(('x','field_1')).rename('d')
print (separate_data1)
x field_1
1 a 1
b 3
c 7
2 a 2
b 5
c 6
3 a 2
b 4
c 4
4 a 2
b 5
c 9
5 a 6
b 1
c 10
Name: d, dtype: int64
如果有必要,可以使用一些函数,主要是如果一对x
与field_1
成对重复,它会返回漂亮的唯一对:
def func(x):
#sample function
return x / 2 + x ** 2
separate_data1 = separate_data1.groupby(level=['x','field_1']).apply(func)
print (separate_data1)
x field_1
1 a 1.5
b 10.5
c 52.5
2 a 5.0
b 27.5
c 39.0
3 a 5.0
b 18.0
c 18.0
4 a 5.0
b 27.5
c 85.5
5 a 39.0
b 1.5
c 105.0
Name: d, dtype: float64
benchmark = benchmark.join(separate_data1, on=['x','field_1'])
print (benchmark)
x y z field_1 d
0 1 1 3 a 1.5
1 1 2 5 b 10.5
2 9 2 4 a NaN
3 1 2 5 c 52.5
4 4 6 1 c 85.5
我认为你不能使用transform
,因为多个列是一起阅读的。
因此请使用join
:
df1 = benchmark.groupby(['field_1']).apply(func)
然后对于新列是多个解决方案,例如使用map
(默认left join
)或here。
两种方法的示例解决方案都是flexible apply。
或者可以使用{{3}},它可以使用新列返回新的DataFrame
。
答案 1 :(得分:1)
尝试这样的事情:
groups = benchmark.groupby(benchmark["field_1"])
benchmark = benchmark.join(groups.apply(your_function), on="field_1")
在your_function中,您可以使用所需的其他列创建新列,例如:平均他们,总结他们等等。
答案 2 :(得分:0)
这是一个有效的例子:
# Sample function that sums x and y, then append the field as string.
def func(x, y, z):
return (x + y).astype(str) + z
benchmark['new_field'] = benchmark.groupby('field_1')\
.apply(lambda x: func(x['x'], x['y'], x['field_1']))\
.reset_index(level = 0, drop = True)
结果:
benchmark
Out[139]:
x y z field_1 new_field
0 1 1 3 a 2a
1 1 2 5 b 3b
2 9 2 4 a 11a
3 1 2 5 c 3c
4 4 6 1 c 10c