为了账号安全,请及时绑定邮箱和手机立即绑定

Python 中的 R 命令“which(apply(data, 2, var)==0)”

Python 中的 R 命令“which(apply(data, 2, var)==0)”

三国纷争 2023-04-18 15:11:23
我想知道如何编写 R 命令which(apply(data, 2, var)==0)... 在 Python 中。现在我正在尝试运行 R 脚本来执行 PCA。但是,pca()只接受非常量列(=方差不为 0)。例如,只有 Col2 可以被接受为以下非常量列:Col1 Col2 Col30.0  1.2  4.00.0  1.5  4.00.0  1.3  4.00.0  1.1  4.0我以为我删除了所有常量列。但是,我收到一个错误:> Error in prcomp.default(data, center = TRUE, scale = TRUE) :   cannot rescale a constant/zero column to unit variance我用谷歌搜索并找到了这个问题和 R 命令解决方案:which(apply(oopsmat, 2, var)==0)它对我有用。该命令指定哪些列仍然不变。因此,我手动删除了列,R 脚本执行了 PCA。现在我想在 Python 中做同样的事情。你会如何用 Python 编写这个 R 命令?#####################################################请不要阅读下文,否则会浪费您的时间。我把这个作为我问了一个愚蠢问题的证据:注意:这个 R 命令很奇怪。正如我所说,我已经从我的数据中删除了所有常量列。此 R 命令表明以下列的方差为 0(摘自大约 50,000 个数据)::  0  0  4  0  19  0  32  61  878  4  1  13  16  14  2  4  13  :  Excel 的差异命令的结果VAR.P是 231.4。这甚至不接近于 0!我不知道发生了什么,我在 Python 中找不到这样的命令。所以,也请解释一下这种奇怪的行为。*我忽略了删除所有异常值的代码,这就是为什么只剩下 0 的原因。
查看完整描述

1 回答

?
墨色风雨

TA贡献1853条经验 获得超6个赞

本质上,R 中的命令apply(data, 2, var)在二维结构(如矩阵或数据帧)上运行(但不建议后者)以计算所有列的方差:


数据框


set.seed(73120)


random_df <- data.frame(

  num1 = runif(500, 1, 100),

  num2 = runif(500, 1, 100),

  num3 = runif(500, 1, 100),

  num4 = runif(500, 1, 100),

  num5 = runif(500, 1, 100)

)


apply(random_df, 2, var)

#     num1     num2     num3     num4     num5 

# 822.9465 902.5558 782.4820 804.1448 830.1097 

一旦which应用,命名向量(即一维数组)的索引将根据逻辑返回。


which(apply(random_df, 2, var) > 900)

# num2 

#    2 

矩阵


set.seed(73120)


random_mat <- replicate(5, runif(500, 1, 100))


apply(random_mat, 2, var)

# [1] 822.9465 902.5558 782.4820 804.1448 830.1097


which(apply(random_mat, 2, var) > 900)

# [1] 2

熊猫

在 Python 中,使用pandas(数据分析库),等效项也适用DataFrame.apply轴设置为index在所有列上运行操作。等价地,您可以运行DataFrame.aggregate. 返回是一个熊猫系列,类似于 R 的命名向量作为一维数组。

import numpy as np

import pandas as pd


np.random.seed(7312020)


random_df = pd.DataFrame({'num1': np.random.uniform(1, 100, 500),

                          'num2': np.random.uniform(1, 100, 500),

                          'num3': np.random.uniform(1, 100, 500),

                          'num4': np.random.uniform(1, 100, 500),

                          'num5': np.random.uniform(1, 100, 500)

                         })


agg1 = random_df.apply('var', axis='index')

print(agg1)

# num1    828.538378

# num2    810.755215

# num3    820.480400

# num4    811.728108

# num5    885.514924

# dtype: float64


agg2 = random_df.aggregate('var')

print(agg2)

# num1    828.538378

# num2    810.755215

# num3    820.480400

# num4    811.728108

# num5    885.514924

# dtype: float64

R可以通过简单的括号(在 R 中也是可行的),或(保持原始尺寸)which来实现:[...].locwhere


agg[agg > 850]

# num5    885.514924

# dtype: float64


agg.loc[agg > 850]

# num5    885.514924

# dtype: float64


agg.where(agg > 850)

# num1           NaN

# num2           NaN

# num3           NaN

# num4           NaN

# num5    885.514924

# dtype: float64

麻木的


另外使用 Python 的numpy(支持数组的数值计算库),您可以使用numpy.apply_along_axis. 并等同于 Pandas' var,相应地调整默认值ddof:


random_arry = random_df.to_numpy()


agg = np.apply_along_axis(lambda x: np.var(x, ddof=1), 0, random_arry)

print(agg)

# [828.53837793 810.75521479 820.48039962 811.72810753 885.51492378]


print(agg[agg > 850])

# [885.51492378]


查看完整回答
反对 回复 2023-04-18
  • 1 回答
  • 0 关注
  • 278 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信