【发布时间】:2018-09-13 17:10:49
【问题描述】:
import numpy as np
import pandas as pd
from scipy.stats import levene as lev
raw_data = {'IDs': ['G1', 'G2', 'G3', 'G4', 'G5'],
'Sample1': [102.2, 2310.4, 123.4, 213.0, 1234.2],
'Sample2': [112.8, 1910.4, 36.3, 188.2, 1271.2],
'Sample3': [32.2, 1290.3, 121.4, 212.3, 1333.5],
'Sample4': [52.1, 2210.1, 155.2, 244.7, 1987.1]}
raw_data2 = {'IDs': ['S1', 'S2', 'S3', 'S4', 'S5'],
'Sample1': [1, 2, 1, 0, 2],
'Sample2': [2, 1, 2, 1, 2],
'Sample3': [2, 0, 1, 0, 1],
'Sample4': [1, 2, 1, 2, 1]}
df1 = pd.DataFrame(raw_data, columns = ['IDs', 'Sample1', 'Sample2', 'Sample3', 'Sample4'])
df2 = pd.DataFrame(raw_data2, columns = ['IDs', 'Sample1', 'Sample2', 'Sample3', 'Sample4'])
我一直在试图找出一种方法来对 df1 的每一行实施 levenes 测试,每一行 df2 定义要拆分的组。例如,每次运行 levenes 测试时,df1 的第一行将按 df2 的每一行分组。显然,我可以使用嵌套循环来实现它,例如(必须包括 if 语句,因为并非所有行都包含所有组):
for i in range(0, df1.shape[0]):
for j in range(0, df2.shape[0]):
tmp1=df1.ix[i,:]
tmp2=df2.ix[i,:]
group1 = tmp1[tmp2==0]
group2 = tmp1[tmp2==1]
group3 = tmp1[tmp2==2]
if len(group1) <= 1:
lev(group2,group3) # and some how return the output to a new df
elif len(group2) <= 1:
lev(group1,group3) # and some how return the output to a new df
elif len(group3) <=1:
lev(group1,group2) # and some how return the output to a new df
else:
lev(group1,group2,group3) # and some how return the output to a new df
样本在数据帧中的顺序相同,但是一个 df 有一些额外的描述符列(对于保留输出很重要)。
由于我将进行数百万次比较,因此使用循环进行比较是不切实际的,我的第一次尝试需要 120 年...我已经对其进行了改进,但需要删除循环以真正改进它。
我一直在阅读有关尝试使用矢量化的信息,我在 R 中使用 apply 函数对它有些熟悉。我想在 pandas、numpy 等中会有一种优雅的方式,但还没有破解它。
为了更清楚,预期的输出会是这样的(抱歉没有计算 lev 测试,所以没有实际数字 - 将在到达计算机时更新):
DF1-ID DF2-ID Lev.stat Lev.pvalue
G1 S1 float float
G1 S2 float float
G1 S3 float float
G1 S4 float float
G2 S1 float float
.
.
.
G4 S4 float float
【问题讨论】:
-
你期望的输出是什么?
-
@asongtoruin 我已将预期输出添加到问题中。请注意,它是一个简化版本,S1 和 G1 实际上是多个描述符列。
标签: python pandas vectorization