从R语言到Python语言的 do.call(rbind, lapply()) 的等价实现方法

6

在我的工作流程中,我主要使用的工具之一是do.call(rbind, lapply()),在R语言中可以像这样进行示例:

df1 <- data.frame(x1 = rnorm(10), x2 = rnorm(10), x3 = rnorm(10))
df2 <- data.frame(x1 = rnorm(10, 5), x2 = rnorm(10), x3 = rnorm(10))

getp <- function(var) {
  return(t.test(df1[, var], df2[, var])$p.value)
}

list <- c('x1', 'x2', 'x3')
ps <- do.call(rbind, lapply(list, getp))
ps
                 [,1]
[1,] 6.232025e-09
[2,] 2.128019e-09
[3,] 5.824713e-08

这将创建一个漂亮的p值列。在实际应用中,我将提取一个仅有一行的数据框,每个列都包含有用的模型统计信息。目标是迭代运行许多相同类型的模型列,并查看其适合度/效果。

在Python中,我可以创建一个类似的功能:

from statsmodels.stats.weightstats import ttest_ind 
import numpy as np
import pandas as pd

df1 = pd.DataFrame({'x1' : np.random.randn(10), 'x2' : np.random.randn(10), 'x3' : np.random.randn(10)}) 
df2 = pd.DataFrame({'x1' : np.random.randn(10)+5, 'x2' : np.random.randn(10)+5, 'x3' : np.random.randn(10)+5}) 
def getp(var):
    print(ttest_ind(df1[var], df2[var])[1])

vars = ['x1', 'x2', 'x3']

我可以通过以下方式将所有p值打印到控制台上:
```python print(pvalues) ```
for i in vars:
    getp(i)

9.67944232638e-08
1.82163637251e-08
2.00410346438e-10

但我想将其保存为一个对象,类似于R中的一个列和三行。这可能吗?

谢谢!

实际函数可能是这样的:

def getMoreThanP(var):
    out = pd.DataFrame({'mean1' : [np.mean(df1[var])], 'mean2' : [np.mean(df2[var])], 'pvalue' : [ttest_ind(df1[var], df2[var])[1]]})
    print(out)

for i in vars:
    getMoreThanP(i)

...     getMoreThanP(i)
     mean1     mean2        pvalue
0  0.24452  4.824327  2.438985e-11
      mean1     mean2        pvalue
0  0.187176  4.969862  1.115546e-11
      mean1     mean2        pvalue
0  0.035759  5.249378  1.525264e-08
1个回答

9

不需要逐个传递变量,可以一次性传递所有三个变量:

ttest_ind(df1[vars], df2[vars])[1]
Out[85]: array([  4.97835813e-11,   8.30544748e-08,   9.24917262e-07])

返回的对象是一个一维数组。如果你想要一个数据框(dataframe)的话,可以尝试以下方法。
pd.DataFrame(ttest_ind(df1[vars], df2[vars])[1])

这主要是因为ttest_ind接受类似数组的对象。对于getMoreThanP,您可以使用pd.concat和map的组合:

def getMoreThanP(var):
    out = pd.DataFrame({'mean1' : [np.mean(df1[var])], 'mean2' : [np.mean(df2[var])], 'pvalue' : [ttest_ind(df1[var], df2[var])[1]]})
    return out

pd.concat(map(getMoreThanP, vars))
# pd.concat(map(getMoreThanP, vars), ignore_index=True) if you want to reset index
Out[134]: 
      mean1     mean2        pvalue
0 -0.021791  4.964985  4.978358e-11
0  0.087019  4.610332  8.305447e-08
0 -0.084168  4.680124  9.249173e-07

请注意,我更改了getMoreThanP的定义,使其返回数据框而不是将其打印出来。

1
我的想法被ttest_ind接受数组的方式震撼了。非常酷。但我不确定它是否解决了我的全部问题,因为我真正想做的是希望对传递的每个变量进行大量操作。我的帖子现在已经更新,更接近我可能编写的函数类型。 - Andrew Taylor
您想要打印值还是返回一个数组(最终是一个3x3的矩阵)? - ayhan
我想返回一个3x3的矩阵 / DataFrame。通过循环方法,我仅知道如何通过print()查看结果,这就是我在这里使用它的原因。我假设我会使用适当的方法使用return。 - Andrew Taylor
正是我所需要的。谢谢! - Andrew Taylor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接