【问题标题】:How can I get descriptive statistics of a NumPy array?如何获得 NumPy 数组的描述性统计信息?
【发布时间】:2016-11-29 17:44:32
【问题描述】:

我使用下面的代码来创建一个 numpy-ndarray。该文件有 9 列。我明确键入每一列:

dataset = np.genfromtxt("data.csv", delimiter=",",dtype=('|S1', float, float,float,float,float,float,float,int))

现在我想获取每列的一些描述性统计信息(最小值、最大值、标准差、平均值、中值等)。不应该有一个简单的方法来做到这一点吗?

我试过这个:

from scipy import stats
stats.describe(dataset)

但这会返回错误:TypeError: cannot perform reduce with flexible type

如何获得创建的 NumPy 数组的描述性统计数据?

【问题讨论】:

  • 我认为错误是因为您的数组中有多个dtype。特别是一个字符串在统计上描述是有问题的。也许您可以遍历每一列,并分别描述这些列?
  • 感谢您的回答。例如,我如何才能访问数组的第二列?我尝试了stats.describe(dataset[2]),但它产生了与我的 OP 中相同的错误。
  • 我怀疑我的阵列可能有问题?基于 CSV 文件的正确 numpy 数组应该是什么样子?我的看起来像这样,如果我打印它:pastebin.com/MYyqbSG0
  • @beta 如果你正在处理非统一数据(看起来你是),你应该看看pandas,它对于这类事情要强大得多。
  • 如果没有给出字段名称,则默认字段名称为'f0''f1'等。所以不要使用stats.describe(dataset[2]),而是使用stats.describe(dataset['f2'])

标签: python numpy multidimensional-array scipy


【解决方案1】:
import pandas as pd
import numpy as np

df_describe = pd.DataFrame(dataset)
df_describe.describe()

请注意,dataset 是您要描述的 np.array。

import pandas as pd
import numpy as np

df_describe = pd.DataFrame('your np.array')
df_describe.describe()

【讨论】:

  • 我认为这是迄今为止最简单的选择。你甚至不需要创建一个新变量,你只需要写pd.DataFrame(my_array).describe()
  • 对于 OP 要求的情况,我认为这个答案的代码应该是 pd.read_csv("data.csv").describe() 而不是暗示数据首先加载到一个 numpy 数组中
  • 只有一行,没有for循环什么都没有。这是最好的答案。
【解决方案2】:

这不是一个很好的解决方案,但它可以完成工作。问题是,通过指定多个 dtypes,您实际上是在制作一个元组的一维数组(实际上是 np.void),它无法由统计信息描述,因为它包括多种不同的类型,包括。字符串。

这可以通过两轮阅读或使用带有read_csv 的熊猫来解决。

如果你决定坚持numpy

import numpy as np
a = np.genfromtxt('sample.txt', delimiter=",",unpack=True,usecols=range(1,9))
s = np.genfromtxt('sample.txt', delimiter=",",unpack=True,usecols=0,dtype='|S1')

from scipy import stats
for arr in a: #do not need the loop at this point, but looks prettier
    print(stats.describe(arr))
#Output per print:
DescribeResult(nobs=6, minmax=(0.34999999999999998, 0.70999999999999996), mean=0.54500000000000004, variance=0.016599999999999997, skewness=-0.3049304880932534, kurtosis=-0.9943046886340534)

请注意,在此示例中,最终数组的 dtypefloat,而不是 int,但可以使用 arr.astype(int) 轻松(如有必要)将其转换为 int

【讨论】:

  • usecols 的这种用法很好。我认为你不需要unpack
  • @hpaulj 如果一个人以您在答案中显示的方式访问数据(我认为这应该是公认的答案),那么 unpack 是不必要的。尽管如此,根据我的经验,无论是使用genfromtxtloadtxt,我发现在处理来自类似csv 的文档的科学数据时,我总是使用列(即正常输出的转置)。遍历recarray 字段也不太容易。
  • 我为嵌套结构打开了一个衍生问题,请参阅stackoverflow.com/questions/62385252/…
【解决方案3】:

如何处理来自genfromtxt 的混合数据的问题经常出现。人们期望一个二维数组,而不是得到一个他们不能按列索引的一维数组。那是因为他们得到了一个结构化数组 - 每列都有不同的 dtype。

genfromtxt 文档中的所有示例都显示了这一点:

>>> s = StringIO("1,1.3,abcde")
>>> data = np.genfromtxt(s, dtype=[('myint','i8'),('myfloat','f8'),
... ('mystring','S5')], delimiter=",")
>>> data
array((1, 1.3, 'abcde'),
      dtype=[('myint', '<i8'), ('myfloat', '<f8'), ('mystring', '|S5')])

但让我演示一下如何访问此类数据

In [361]: txt=b"""A, 1,2,3
     ...: B,4,5,6
     ...: """
In [362]: data=np.genfromtxt(txt.splitlines(),delimiter=',',dtype=('S1,int,float,int'))
In [363]: data
Out[363]: 
array([(b'A', 1, 2.0, 3), (b'B', 4, 5.0, 6)], 
      dtype=[('f0', 'S1'), ('f1', '<i4'), ('f2', '<f8'), ('f3', '<i4')])

所以我的数组有 2 条记录(检查形状),它们在列表中显示为元组。

您按名称访问fields,而不是按列号(我需要添加结构化数组文档链接吗?)

In [364]: data['f0']
Out[364]: 
array([b'A', b'B'], 
      dtype='|S1')
In [365]: data['f1']
Out[365]: array([1, 4])

如果我选择带有“子数组”的dtype,在这种情况下可能会更有用。这是一个更高级的 dtype 主题

In [367]: data=np.genfromtxt(txt.splitlines(),delimiter=',',dtype=('S1,(3)float'))
In [368]: data
Out[368]: 
array([(b'A', [1.0, 2.0, 3.0]), (b'B', [4.0, 5.0, 6.0])], 
      dtype=[('f0', 'S1'), ('f1', '<f8', (3,))])
In [369]: data['f1']
Out[369]: 
array([[ 1.,  2.,  3.],
       [ 4.,  5.,  6.]])

字符列仍加载为S1,但数字现在位于 3 列数组中。请注意,它们都是浮点数(或整数)。

In [371]: from scipy import stats
In [372]: stats.describe(data['f1'])
Out[372]: DescribeResult(nobs=2, 
   minmax=(array([ 1.,  2.,  3.]), array([ 4.,  5.,  6.])),
   mean=array([ 2.5,  3.5,  4.5]), 
   variance=array([ 4.5,  4.5,  4.5]), 
   skewness=array([ 0.,  0.,  0.]), 
   kurtosis=array([-2., -2., -2.]))

【讨论】:

    【解决方案4】:

    Scipy 官方文档Example

    #INPUT
    from scipy import stats
    a = np.arange(10)
    stats.describe(a)
    
    #OUTPUT
    DescribeResult(nobs=10, minmax=(0, 9), mean=4.5, variance=9.166666666666666,
                   skewness=0.0, kurtosis=-1.2242424242424244)
    
    #INPUT
    b = [[1, 2], [3, 4]]
    stats.describe(b)
    
    #OUTPUT
    DescribeResult(nobs=2, minmax=(array([1, 2]), array([3, 4])),
                   mean=array([2., 3.]), variance=array([2., 2.]),
                   skewness=array([0., 0.]), kurtosis=array([-2., -2.]))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-11
      • 2012-08-29
      • 1970-01-01
      相关资源
      最近更新 更多