【问题标题】:Python 3: handling numpy arrays and export via openpyxlPython 3:处理 numpy 数组并通过 openpyxl 导出
【发布时间】:2017-03-12 05:02:45
【问题描述】:

我正在处理一个由多个列表组成的数组。在每个子列表中,我想取平均值和标准。偏差,并将它们写在 Excel 表中。

我的代码完成了它的工作,但它让我很头疼,因为我觉得我根本没有有效地使用 python,尤其是在步骤 (2) 中,我逐步使用 numpy。另外,我不明白为什么我必须在步骤(3)中进行修改,以便将数据(“total”)以我可以提供给 openpyxl 编写器(“total_list”)的形式提供。我将不胜感激任何帮助使它更优雅,这是我的代码:

import numpy as np
from openpyxl import Workbook
from itertools import chain

# (1) Make up sample array:
arr = [[1,1,3], [3,4,2], [4,4,5], [6,6,5]]

# (2) Make up lists containing average values and std. deviations
avg = []
dev = []

for i in arr:
    avg.append(np.mean(i))
    dev.append(np.std(i))

# (3) Make an alternating list (avg 1, dev 1, avg 2, dev 2, ...)
total = chain.from_iterable( zip( avg, dev ) )

# (4) Make an alternative list that can be fed to the xlsx writer
total_list = []
for i in total:
    total_list.append(i)

# Write to Excel file
wb = Workbook()
ws = wb.active

ws.append(total_list)
wb.save("temp.xlsx")

我想要附上图片中显示的格式。重要的是,所有数据都在一行中。

【问题讨论】:

  • 你能发布一个想要的数据集吗?你希望它是什么形状的?
  • 您在尝试执行此操作时遇到了哪些问题? openpyxl 支持 numpy 类型。

标签: numpy python-3.5 openpyxl


【解决方案1】:

numpy 代码的改进:

In [272]: arr = [[1,1,3], [3,4,2], [4,4,5], [6,6,5]]

从此列表中创建一个数组。这不是必需的,因为 np.mean 在幕后进行,但它应该有助于可视化操作。

In [273]: arr = np.array(arr)
In [274]: arr
Out[274]: 
array([[1, 1, 3],
       [3, 4, 2],
       [4, 4, 5],
       [6, 6, 5]])

现在计算整个数组的均值和标准差;使用axis=1 作用于行。所以你不要迭代arr的子列表。

In [277]: m=np.mean(arr, axis=1)
In [278]: s=np.std(arr, axis=1)
In [279]: m
Out[279]: array([ 1.66666667,  3.        ,  4.33333333,  5.66666667])
In [280]: s
Out[280]: array([ 0.94280904,  0.81649658,  0.47140452,  0.47140452])

有多种方法可以将这 2 个数组转换为交错数组。一种是将它们垂直堆叠,然后转置。这是numpy 列表zip(*...) 技巧的答案。

In [281]: data=np.vstack([m,s])
In [282]: data
Out[282]: 
array([[ 1.66666667,  3.        ,  4.33333333,  5.66666667],
       [ 0.94280904,  0.81649658,  0.47140452,  0.47140452]])
In [283]: data=data.T.ravel()
In [284]: data
Out[284]: 
array([ 1.66666667,  0.94280904,  3.        ,  0.81649658,  4.33333333,
        0.47140452,  5.66666667,  0.47140452])

我没有openpyxl', but can write a csv withsavetxt`:

In [296]: np.savetxt('test.txt',[data],fmt='%f', delimiter=',',header='#mean1 std1 ...')
In [297]: cat test.txt

# #mean1 std1 ...
1.666667,0.942809,3.000000,0.816497,4.333333,0.471405,5.666667,0.471405

我使用[data],因为data,计算结果是1d,savetxt 会将其保存为一列。它迭代数据的“行”。

【讨论】:

    【解决方案2】:

    我会使用 Pandas 模块,因为它可以很容易地完成所有提到的任务:

    import pandas as pd
    
    df = pd.DataFrame(arr)
    
    In [250]: df
    Out[250]:
       0  1  2
    0  1  1  3
    1  3  4  2
    2  4  4  5
    3  6  6  5
    
    In [251]: df.T
    Out[251]:
       0  1  2  3
    0  1  3  4  6
    1  1  4  4  6
    2  3  2  5  5
    
    In [252]: df.T.mean()
    Out[252]:
    0    1.666667
    1    3.000000
    2    4.333333
    3    5.666667
    dtype: float64
    
    In [253]: df.T.std(ddof=0)
    Out[253]:
    0    0.942809
    1    0.816497
    2    0.471405
    3    0.471405
    dtype: float64
    

    您还可以轻松地将 DataFrame 保存为 Excel 文件:

    df.to_excel(r'/path/to/file.xlsx', index=False)
    

    总共:

    In [260]: df['avg'] = df.mean(axis=1)
    
    In [261]: df['dev'] = df.std(axis=1, ddof=0)
    
    In [262]: df
    Out[262]:
       0  1  2       avg       dev
    0  1  1  3  1.666667  0.816497
    1  3  4  2  3.000000  0.707107
    2  4  4  5  4.333333  0.408248
    3  6  6  5  5.666667  0.408248
    
    In [263]: df.to_excel('d:/temp/result.xlsx', index=False)
    

    结果.xlsx:

    【讨论】:

    • FWIW openpyxl 现在可以处理 Dataframe 对象,让用户可以更好地控制输出。
    • @CharlieClark,您能分享一些指向新功能(示例)的链接吗?
    猜你喜欢
    • 1970-01-01
    • 2011-11-26
    • 1970-01-01
    • 2020-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-31
    • 2021-03-19
    相关资源
    最近更新 更多