【问题标题】:Construct structured numpy array from a file?从文件构造结构化的numpy数组?
【发布时间】:2023-04-02 09:14:01
【问题描述】:

我的任务是在 python 中编写一个简单的 MD-Simulation 程序,它不使用 python 内置类型(dict、list),而只使用 numpy 数组。据我了解,这允许编译代码以更快地运行。在我的代码中的某一时刻,我想从一个类似字典的对象中获取原子的质量,该对象可以通过元素名称(如MassDict['N'] = 14.0067)进行切片。

根据我的阅读,我需要使用结构化的 numpy 数组。我现在要做的是使用以下表格打开我的文件:

H 1.008
He 4.003
Li 6.941

然后构造一个结构化的numpy数组,可以使用第一列的元素名称进行切片。

我尝试制作两个 numpy 数组,然后将它们连接起来,但这似乎不是我需要的。我的代码一开始看起来并不那么好。那么如何创建一个 numpy 对象,该对象可以最佳地从文本文件中按字符串切片? 这是我的代码:

import numpy as np
import re

def mass_el(file):

    with open(file) as inf:

        for i, line in enumerate(inf):
            pass

        elements = np.empty((i+1),dtype='S2')
        masses = np.empty((i+1),dtype=np.float32)


    with open(file) as inf:

        for i, line in enumerate(inf):
            elements[i] = re.search('[a-zA-Z]+',line).group()
            masses[i] = re.search('\d+[.]\d+',line).group()

    #???


mass_el('elements.txt')

【问题讨论】:

  • 你总共有多少个条目?只有那三个?
  • 这就是第一个with open... pass 的用途。它计算行数并创建具有适当数量条目的np.empty 数组。我在复制代码时是否弄乱了缩进?我认为数组需要向左缩进...
  • 但是你总共有多少个?如果只有三个,dict 很可能比np.ndarray 更有意义
  • 108 个 Element Mass 条目。顺便说一句,我不能使用 python 内置函数,因为它们显然不能被编译器加速。
  • 您可能误解了使用numpy的原因。正确使用这些数组会更快,因为它们使用已编译的代码。但是错误的使用(迭代)速度较慢。好的代码在适当的地方使用列表和字典。

标签: python file numpy structured-array


【解决方案1】:

使用 numpy

您可以使用numpy loadtxt 函数,如果文件中的数据字段定期分隔(CSV 文件),您可以直接从文件中读取和格式化数据。

m_els = np.loadtxt('elements.txt', dtype={'names':('element', 'mass'), 'formats':('U2', 'f')})

使用您的 3 行文件,您将获得以下 m_els 数组:

array([('H', 1.008), ('He', 4.003), ('Li', 6.941)],
    dtype=[('element', '<U2'), ('mass', '<f4')])

我猜这就是你想要的。要获得一个元素,比如氢,请执行m_els[0] 以获得第一个元组。 m_els[0][1] 获取氢气质量。

使用熊猫

使用pandas 更容易,而且速度也很快,因为它建立在numpy 之上。

import pandas as pd
m_els = pd.read_csv('elements.txt', sep='\s+', header=None, names=['element', 'mass'])

在这种情况下,m_els 是一个数据框,其中元素名称用作索引:

  element   mass
0       H  1.008
1      He  4.003
2      Li  6.941

要获取与某个元素(例如氢)对应的行,请执行 m_els.iloc[0]。要获得氢的质量,请执行 m_els.loc[0, 'mass'] 或使用元素名称 m_els['mass'].loc[m_els['element'] == 'H']

【讨论】:

  • m_els['mass'][0] 获取第一个条目的质量。这看起来像正确的结构化数组,但我看不出它对 dict 有何改进。
  • 我既不诚实,但 OP 明确询问如何使用 numpy 执行此操作并且不使用字典。
  • 正如我所说,我是类型转换的新手(直到此时我才使用 python,我很惊讶地了解了内存分配)。所以我不知道某种对象类型如何影响性能,以及你可以用编译器加速它的速度。它不是真的有影响力,所以我可以只使用一个 dict 吗?
  • 这取决于您如何使用这些数据结构。如果您只需要几次选择正确的质量,那么字典就很好了。如果您需要进行矢量化计算(例如选择所有质量作为矢量并执行一些操作),那么最好使用 numpy.比编写 for 循环来收集字典中的所有内容要快。
猜你喜欢
  • 2019-05-08
  • 1970-01-01
  • 2023-04-06
  • 2018-12-19
  • 1970-01-01
  • 2021-02-25
  • 2016-03-29
  • 2012-08-12
  • 2016-04-28
相关资源
最近更新 更多