【问题标题】:Python: how to do basic data manipulation like in R?Python:如何像在 R 中一样进行基本的数据操作?
【发布时间】:2011-02-04 15:42:19
【问题描述】:

我使用 R 已经有好几年了。 R 在数据处理方面非常强大。我正在学习 python,我想知道如何使用 python 操作数据。基本上我的数据集被组织为数据框(例如 excel 表)。我想知道(通过示例)如何使用 python 完成这种基本的数据操作任务?

1. Read csv file like the following

var1, var2, var3
1, 2, 3
4, 5, 6 
7, 8, 9

2. Subset data where var2 in ('5', '8') 
3. Make a new variable --> var4 = var3 * 3
4. Transpose this data
5. Write to csv file

非常感谢您的帮助和示例!

【问题讨论】:

  • 我怀疑这可能会被关闭,它 veryvery 含糊不清。你不明白哪些部分?变量赋值?如果是这种情况,请阅读教程,然后返回具体问题。如果只是如何读写 csv 文件的问题,那么就这样写你的问题。

标签: python r


【解决方案1】:

我不同意 Cpfohl 的评论 - 可能是因为我自己也经历过同样的转变,而天真的用户如何能够更准确地表述问题并不明显。这实际上是目前一个活跃的开发问题,许多项目都提出了不重叠的功能(例如,在金融时间序列世界、大脑成像世界等)。

简短的回答是,python 处理表格和 csv 文件的各种库对于初学者来说不如 R 中的库好,这是多年不同级别用户的最终结果。

首先,看看 numpy.这可能是常用库中最接近的数据结构,类似于 R 中的 data.frame。特别是,您可能会喜欢 numpy.recfromcsv 函数,尽管它不如例如R 中的 read.csv(例如,它会遇到非标准行尾问题)。

对一个recarray 进行子集化很容易(尽管创建一个可能看起来很笨重):

import numpy as np
mydata = np.array([(1.0, 2), (3.0, 4)], dtype=[('x', float), ('y', int)])
mydata = mydata.view(np.recarray)
mydata[mydata.x > 2]

修改 numpy 数组的性质通常不像在 R 中那么容易,但在 numpy.lib.recfunctions 中有一个很好的函数库(必须单独导入 - 它没有简单的 import numpy )。特别是,请查看 rec_append_fields 和 rec_join 以添加列。

Numpy 有一个函数numpy.savetxt,它将接受一个简单的分隔符参数来创建一个 csv 文件,但它不会遗憾地打印列名(至少,我不认为它会打印)。因此,虽然我不鼓励添加不必要的库(因为它提供的可移植代码较少),但您可能只使用 matplotlib.mlab.rec2csv(您也会在该社区找到一些其他类似的功能 - numpy 社区正在尝试移植通常有用的数字 /数据操纵代码到 numpy 正确。谁知道,也许你会这样做?)。

你会注意到我没有回答 (4),因为那没有意义。表格不会在 python 或 R 中转置。数组或矩阵可以。因此,将您的数据转换为具有统一 dtype 的数组,然后只需使用 myarray.T。

您可能会看到的其他工具是 pytables(以及相关的包 carray)、larry、dataarray、pandas 和 tabular。特别是,dataarray 正在寻求为标记数据数组创建一个系统,该系统将作为其他项目的基础(我认为来自 larry 和 pandas 项目的开发人员也是如此)。

希望对您有所帮助! 戴夫

【讨论】:

  • 对于开始涉足 Python 的人来说,这是非常有见地的。 +1
  • 我不得不说,鉴于 pandas 在哪里,我现在完全同意 @Wes McKinney 在下面的回答。
【解决方案2】:
import csv
from itertools import izip

with open('source.csv') as f:
    reader = csv.reader(f)
    # filter data
    data = (row for row in reader if row[1].strip() in ('5', '8'))
    # make a new variable
    data = (row + [int(row[2]) * 3] for row in data)
    # transpose data
    data = izip(*data)
    # write data to a new csv file
    with open('destination.csv', 'w') as fw:
        csv.writer(fw).writerows(data)

【讨论】:

  • 谢谢,很好的例子,正是要找的东西!
  • 对于看这个问题的人来说,你真的应该看看 Wes McKinney 下面关于pandas 的答案。
【解决方案3】:

简单回答:使用pandas

1

In [2]: df = read_csv('foo.csv', index_col=None)

In [3]: df
Out[3]: 
   var1  var2  var3
0  1     2     3   
1  4     5     6   
2  7     8     9   

2

In [4]: df[df['var2'].isin([5, 8])]
Out[4]: 
   var1  var2  var3
1  4     5     6   
2  7     8     9   

3

In [5]: df['var4'] = df['var3'] * 2

In [6]: df
Out[6]: 
   var1  var2  var3  var4
0  1     2     3     6   
1  4     5     6     12  
2  7     8     9     18  

4

In [7]: df.T
Out[7]: 
      0  1   2 
var1  1  4   7 
var2  2  5   8 
var3  3  6   9 
var4  6  12  18

6

In [8]: df.to_csv('foo2.csv')

In [9]: !cat foo2.csv
index,var1,var2,var3,var4
0,1,2,3,6
1,4,5,6,12
2,7,8,9,18

【讨论】:

    【解决方案4】:

    标准库中有一个module for CSV parsing。要获取每个包含单元格列表的行列表,您可以使用list(csv.reader(...))

    第 2 步和第 3 步可以写在一个列表理解中:[(var1, var2, var3, var3 * 3) for var1, var2, var3 in data if var2 in ('5', '8')]

    我不知道标准库中有任何用于转置列表的内容。也许 NumPy 或 SciPy 有一些东西。一种快速而肮脏的方法是压缩行 (zip(*lists))。

    写回文件应该像构造 csv.writer 并在循环中传递每一行一样简单。

    【讨论】:

    • zip(甚至更好的 izip)确实是在标准库中转置列表的最佳方式。
    猜你喜欢
    • 1970-01-01
    • 2021-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-27
    • 2021-05-07
    相关资源
    最近更新 更多