【问题标题】:Using numpy to extract data from CSV file使用 numpy 从 CSV 文件中提取数据
【发布时间】:2017-07-24 22:49:57
【问题描述】:

我正在与numpy 合作,并试图找出哪个平台在北美地区的销量最高。

我有一个包含大量数据的 CSV 文件,如下所示:

Rank,Name,Platform,Year,Genre,Publisher,NA_Sales,EU_Sales,JP_Sales,Other_Sales,Global_Sales
1,Wii Sports,Wii,2006,Sports,Nintendo,41.49,29.02,3.77,8.46,82.74
2,Super Mario Bros.,NES,1985,Platform,Nintendo,29.08,3.58,6.81,0.77,40.24
3,Mario Kart Wii,Wii,2008,Racing,Nintendo,15.85,12.88,3.79,3.31,35.82
4,Wii Sports Resort,Wii,2009,Sports,Nintendo,15.75,11.01,3.28,2.96,33
5,Pokemon Red/Pokemon Blue,GB,1996,Role-Playing,Nintendo,11.27,8.89,10.22,1,31.37
6,Tetris,GB,1989,Puzzle,Nintendo,23.2,2.26,4.22,0.58,30.26
7,New Super Mario Bros.,DS,2006,Platform,Nintendo,11.38,9.23,6.5,2.9,30.01
8,Wii Play,Wii,2006,Misc,Nintendo,14.03,9.2,2.93,2.85,29.02
9,New Super Mario Bros. Wii,Wii,2009,Platform,Nintendo,14.59,7.06,4.7,2.26,28.62
10,Duck Hunt,NES,1984,Shooter,Nintendo,26.93,0.63,0.28,0.47,28.31
11,Nintendogs,DS,2005,Simulation,Nintendo,9.07,11,1.93,2.75,24.76

我想打印北美地区销售额和销售额最高的平台。我该怎么做?

【问题讨论】:

  • 到目前为止你尝试了什么?
  • 我将所有不同的平台硬编码为掩码,例如:maskNES = (data[:,2] == 'NES'),然后我将其分配给一个变量,例如:pfNES = data[maskNES] [:,6].sum() 最后,我比较了所有平台以找到价值最高的平台。这似乎是一种愚蠢的做法。如果我有成千上万个不同的平台哦,我将 csv 数据放入一个名为“数据”的矩阵中

标签: python csv pandas numpy


【解决方案1】:

genfromtxt 加载这个很简单:

In [280]: data=np.genfromtxt('stack42602390.csv',delimiter=',',names=True, dtype=None)

In [281]: data
Out[281]: 
array([ ( 1, b'Wii Sports', b'Wii', 2006, b'Sports', b'Nintendo',  41.49,  29.02,   3.77,  8.46,  82.74),
       ( 2, b'Super Mario Bros.', b'NES', 1985, b'Platform', b'Nintendo',  29.08,   3.58,   6.81,  0.77,  40.24),
       ( 3, b'Mario Kart Wii', b'Wii', 2008, b'Racing', b'Nintendo',  15.85,  12.88,   3.79,  3.31,  35.82),
....
       (11, b'Nintendogs', b'DS', 2005, b'Simulation', b'Nintendo',   9.07,  11.  ,   1.93,  2.75,  24.76)], 
      dtype=[('Rank', '<i4'), ('Name', 'S25'), ('Platform', 'S3'), ('Year', '<i4'), ('Genre', 'S12'), ('Publisher', 'S8'), ('NA_Sales', '<f8'), ('EU_Sales', '<f8'), ('JP_Sales', '<f8'), ('Other_Sales', '<f8'), ('Global_Sales', '<f8')])

b'string' 只是 Python3 显示字节串的方式,genfromtxt 的默认字符串格式。它们不会在 Py2 中显示。

结果是一个结构化数组,具有不同的字段名称和类型。它不是具有行和列的二维数组。

NA_Sales 数据:

In [282]: data['NA_Sales']
Out[282]: 
array([ 41.49,  29.08,  15.85,  15.75,  11.27,  23.2 ,  11.38,  14.03,
        14.59,  26.93,   9.07])

以及其中的最大值:

In [283]: np.argmax(data['NA_Sales'])
Out[283]: 0

以及对应的记录:

In [284]: data[0]
Out[284]: (1, b'Wii Sports', b'Wii', 2006, b'Sports', b'Nintendo',  41.49,  29.02,  3.77,  8.46,  82.74)

要充分利用这个数组,您必须阅读结构化数组。

【讨论】:

  • 尝试了这个解决方案,但遇到了问题,在我的 csv 文件中,标题中有逗号,我无法将 quotechar=' " ' 添加到 np.getfromtext
  • csv 包处理引号,但 numpy 读者不处理。 genfromtxt 接受来自任何提供行的输入,因此您可以对行进行预处理,清理它们,以便可以使用简单的分隔符对其进行解析。这已经在之前的许多 SO 问题中讨论过。
  • 带有过滤器输入的genfromtxt 的最新示例:stackoverflow.com/a/42593389/901925
【解决方案2】:

对于 pandas,这相当简单。

代码:

# read csv data into a dataframe
df = pd.read_csv(data, skipinitialspace=True)

# roll up by NA Sales
platform_roll_up = df.groupby('Platform')['NA_Sales'].sum()

# find row with max sales
idx_max = platform_roll_up.idxmax()

# show platform and sales for max
print(idx_max, platform_roll_up[idx_max])

结果:

Wii 101.71

测试数据:

data = StringIO(u"""
    Rank,Name,Platform,Year,Genre,Publisher,NA_Sales,EU_Sales,JP_Sales,Other_Sales,Global_Sales
    1,Wii Sports,Wii,2006,Sports,Nintendo,41.49,29.02,3.77,8.46,82.74
    2,Super Mario Bros.,NES,1985,Platform,Nintendo,29.08,3.58,6.81,0.77,40.24
    3,Mario Kart Wii,Wii,2008,Racing,Nintendo,15.85,12.88,3.79,3.31,35.82
    4,Wii Sports Resort,Wii,2009,Sports,Nintendo,15.75,11.01,3.28,2.96,33
    5,Pokemon Red/Pokemon Blue,GB,1996,Role-Playing,Nintendo,11.27,8.89,10.22,1,31.37
    6,Tetris,GB,1989,Puzzle,Nintendo,23.2,2.26,4.22,0.58,30.26
    7,New Super Mario Bros.,DS,2006,Platform,Nintendo,11.38,9.23,6.5,2.9,30.01
    8,Wii Play,Wii,2006,Misc,Nintendo,14.03,9.2,2.93,2.85,29.02
    9,New Super Mario Bros. Wii,Wii,2009,Platform,Nintendo,14.59,7.06,4.7,2.26,28.62
    10,Duck Hunt,NES,1984,Shooter,Nintendo,26.93,0.63,0.28,0.47,28.31
    11,Nintendogs,DS,2005,Simulation,Nintendo,9.07,11,1.93,2.75,24.76
""")

【讨论】:

  • 感谢您的快速回答!我正在尝试使用适用于 numpy.ndarray 的解决方案。没有 iloc 属性。在这种情况下我应该远离 ndarray 吗?此外,我正在尝试查找 X 平台所有产品的总 NA_Sales 值。而不是找到最高的单个值。顺便说一句,我是 python 新手
  • 非常感谢!非常感谢您的回答,您的编辑版本正是我想要的。
猜你喜欢
  • 2018-12-10
  • 1970-01-01
  • 1970-01-01
  • 2021-05-22
  • 2018-04-24
  • 1970-01-01
  • 2018-05-20
  • 2022-06-11
  • 2018-05-18
相关资源
最近更新 更多