嘿我正在寻找一个从DataFrame组中获取结果的pandas解决方案,然后将这些结果应用于完整的数据帧。这是我现在正在做的最小例子,但我发现它不是很好。
New data: a:1:{s:2:"ep";d:5.07333729617E+13;}
给出了这是我正在使用的缩减版本:
import pandas as np
data = [[0.0, 2.4285714285714286, '0', 'mica02', 'd2o'],
[10.0, 1.4285714285714286, '225', 'mica02', 'd2o'],
[13.0, 1.0833333333333333, '225', 'mica02', 'd2o'],
[954.0, 5.420454545454546, '225', 'mica02', 'air'],
[937.0, 5.162534435261708, '225', 'mica02', 'air'],
[75.0, 0.4966887417218543, '225', 'mica02', 'h2o'],
[78.0, 0.49523809523809526, '225', 'mica02', 'h2o'],
[80.0, 0.49323809523809526, '225', 'mica01', 'h2o'],
]
df0 = pd.DataFrame(data, columns=['basesubed', 'normalized', 'rot', 'm0', 'm1'])
df0
现在,按 basesubed normalized rot m0 m1
0 0.0 2.428571 0 mica02 d2o
1 10.0 1.428571 225 mica02 d2o
2 13.0 1.083333 225 mica02 d2o
3 954.0 5.420455 225 mica02 air
4 937.0 5.162534 225 mica02 air
5 75.0 0.496689 225 mica02 h2o
6 78.0 0.495238 225 mica02 h2o
7 80.0 0.493238 225 mica01 h2o
和m0
元数据对DataFrame进行分组,并计算组中的内容。让我们说现在的中位数:
rot
现在我想从原始DataFrame中减去结果,但只有当mask = (df0.m1 == 'h2o')
gdf = df0[mask].groupby(['m0', 'rot']).median()
gdf
basesubed normalized basesubed_n normalized_n
m0 rot
mica01 225 80.0 0.493238 1.0 1.0
mica02 225 76.5 0.495963 1.0 1.0
的多索引与gdf
中的元数据匹配时才会这样做:
df0
我得到了:
for i in range(len(gdf.index.values)):
mask = ((df0.m0 == gdf.index.values[i][0]) & (df0.rot == gdf.index.values[i][1]))
df0.loc[mask, 'basesubed_n'] = df0[mask]['basesubed'] / gdf.loc[gdf.index.values[i]].basesubed
df0.loc[mask, 'normalized_n'] = df0[mask]['normalized'] / gdf.loc[gdf.index.values[i]].normalized
df0
注意第一行是如何得到NaN的,因为它在gdf中没有匹配的条目。这正是我想要的,因为 basesubed normalized rot m0 m1 basesubed_n normalized_n
0 0.0 2.428571 0 mica02 d2o NaN NaN
1 10.0 1.428571 225 mica02 d2o 0.130719 2.880397
2 13.0 1.083333 225 mica02 d2o 0.169935 2.184301
3 954.0 5.420455 225 mica02 air 12.470588 10.929142
4 937.0 5.162534 225 mica02 air 12.248366 10.409103
5 75.0 0.496689 225 mica02 h2o 0.980392 1.001462
6 78.0 0.495238 225 mica02 h2o 1.019608 0.998538
7 80.0 0.493238 225 mica01 h2o 1.000000 1.000000
中没有rot=0
和m1=h2o
。这种不匹配也是为什么我找不到使用df0
的解决方案的原因,因为它也与我想要的数据框的形状不匹配。
任何帮助都会被包围。
答案 0 :(得分:1)
我不了解您要使用的transform
方法,但您可以使用merge
来阻止循环for
。这是一个想法:
# gdf is slightly different, just reset indexes to merge on them later
gdf = df0[mask].groupby(['m0', 'rot']).median().reset_index()
# merge df0 with gdf on the two columns 'm0', 'rot'
df0 = df0.merge(gdf, on = ['m0', 'rot'], how = 'left', suffixes = ('','_median'))
# now you can calculate the column _n such as:
df0['basesubed_n'] = df0['basesubed'] / df0['basesubed_median']
df0['normalized_n'] = df0['normalized'] / df0['normalized_median']
# finally, drop the columns _median
df0 = df0.drop(['basesubed_median','normalized_median'],1)
你得到的输出与你的输出相同
编辑:实际上,我找到了transform
的答案,只是这样做:
df0[['basesubed_n','normalized_n']] = df0.groupby(['m0', 'rot'])\
.transform(lambda x: x/x[mask].median())