【问题标题】:Python numpy split a csv file by the values of a string columnPython numpy 按字符串列的值拆分 csv 文件
【发布时间】:2013-07-07 19:21:31
【问题描述】:

我在 csv 文件中有 5000 行数据,如下所示,我想使用 numpy 数组按最后一列 6(即 A、B)分组,因为之后我将在每个组中绘制数据.

Title
Date, Time, Value1, Value2, Value3, Value4, Value5
,, Unit1, Unit2, Unit3,,
2012-04-02,00:00, 85.5333333333333, 4.87666666666667,    8.96,  323.27,A
2012-04-02,00:30, 196.5, 5.49,    8.42,  323.15,B
2012-04-02,01:00, 68.2, 4.47,    7.83,  325.30,A
2012-04-02,01:30, 320.9, 6.77333333333333,    8.05,  326.63,B

当我使用 np.genfromtxt 加载数据时,我必须指定 dtype=None,否则 A 项将变为 NaN How to use numpy.genfromtxt when first column is string and the remaining columns are numbers?

我正在尝试使用 itertools groupby 根据最后一列返回所有值,此处提到:How do I use Python's itertools.groupby()? 但首先,我需要对 numpy 数组进行排序。

我尝试使用高级索引,通过拼接第六列并对其进行排序 Python (Numpy) array sorting IE。 v[v[:,0].argsort()]

但是,这里有一个链接提到 numpy 会将我的记录视为我的 dtype 的一维数组(设置为 none),我在尝试对此进行排序时遇到了相同的索引错误: Numpy Array Column Slicing Produces IndexError: invalid index Exception

问题:

1) 如何根据第 6 列的字符串值使用 groupby 拆分 numpy 数组,以便分别绘制它们?

2) 能够跳过也很好,这样我就可以跳过第一行(标题)和第三行(单位)并留下第二行(列标题)和数据。任何人都知道如何使用可用选项轻松做到这一点?

这是我目前的脚本:

import numpy as np
from matplotlib import pyplot as plt
from itertools import groupby
import csv

regression_data_dp1 = np.genfromtxt(“file.csv”, delimiter=',', skiprows=3, dtype=None)

sortindex = regression_data_dp1[:,6]

#Error is hit at this step:
#    sortindex = regression_data_dp1[:,6]
#IndexError: invalid index

regression_data_dp1_sorted = regression_data_dp1[ regression_data_dp1(:,column_WRF_wind_direction).argsort()]

for key, group in groupby(regression_data_dp1, lambda x: x[0]):
    print key

    with open(“file_" + key.strip() + ".csv", 'w') as data_file:
        wr=csv.writer(data_file, quoting=csv.QUOTE_ALL)
        for item in (group):            
            wr.writerow(item)

【问题讨论】:

  • 什么是Title?标题多于数据字段;数据文件是这样的吗?
  • @drewk 标题只是文件的描述,即。 “这是……等的报告”。第二行是标题,有7个标题。下一行是单位。然后数据也有 7 列。

标签: python sorting numpy group-by


【解决方案1】:

为了一个例子,让我们让你的 csv 文件更简单

from StringIO import StringIO
import numpy as np
import itertools

data = StringIO("""
Col1,Col2,Col3
1,2,A
2,3,B
8,7,A
""".strip())
arrays = np.genfromtxt(data, dtype=object, delimiter=',', skip_header=1)
sorted_arrays = arrays[np.argsort(arrays[:, 2])] # now it's sorted - yeehaw!

for k, group in itertools.groupby(arrays, lambda x: x[2]):
    # do something

正如我在其他地方所说,让你的生活更轻松,并使用 pandas 加载数据和组(确保你先运行data.seek(0)):

import pandas as pd

df = pd.read_csv(data)
for k, group in df.groupby(["Col3"]):
    # do something with group

此外,您甚至可以使用数据框本身进行绘图。

【讨论】:

  • 感谢您提供一个更简单的示例,我将 dtype=object 添加到我的初始示例中,现在排序工作正常。从 numpy.dtype 文档中并不清楚这是排序所必需的。现在,我对 numpy 没问题,但感谢分享熊猫。
  • @user2412730 你需要 dtype=object 来防止字符串被转换为NaN。排序不依赖于dtype=object,它只依赖于实际不同的值(如果它们都是NaN,则不会发生)
  • 不指定 dtype,字符串显示为 NaN。我之前尝试指定 dtype=None,但字符串没有显示为 NaN,而是显示为实际字符串。但是,在我更改 dtype=object 之前,排序会出现 Index 错误。
【解决方案2】:

您可以使用group = arr[arr['f6']==key] 来选择具有相同key 的行,而不是对数组的行进行排序,并使用itertools.groupby

import numpy as np
import csv

def load_csv(filename):
    with open(filename) as f:
        next(f)
        header = [item.strip() for item in next(f).split(',')]
    arr = np.genfromtxt("file.csv", delimiter=',', skiprows=3, dtype=None)
    arr.dtype.names = header
    return arr

arr = load_csv("file.csv")
keys = np.unique(arr['Value5'])

for key in keys:
    group = arr[arr['Value5']==key]
    filename = 'file_{}.csv' .format(key.strip())
    with open(filename, 'w') as data_file:
        wr = csv.writer(data_file, quoting=csv.QUOTE_ALL)
        wr.writerows(group)

没有直接的工具告诉np.genfromtxt 使用第二行作为标题。最简单的方法可能是打开文件,将第二行插入标题列表,关闭文件,然后使用genfromtxt 加载数组并使用arr.dtype.names = header 为结构化数组提供所需的列名。

【讨论】:

  • 谢谢,我喜欢这种分组方式,因为它可以让我立即从组中获取一列进行绘图,而 groupby 无法做到这一点。 IE。 from matplotlib import pyplot as plt for key in keys: … value3 = group['Value3'] value4 = group['Value4'] plt.scatter(value3, value 4) plt.show()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多