在pandas中格式化数据

时间:2014-01-02 12:39:03

标签: python python-2.7 csv pandas import-from-csv

我试图运行代码:

import pandas as pd

df = pd.read_csv('test.csv', sep=',', header=None, names=['datatable', 'col'])

def replace_letter(group):
    letters = group.isin(['T', 'Q'])              # select letters
    group[letters] = int(group[~letters].max()) + 1  # replace by next max
    return group


df['col'] = df.groupby('datatable').transform(replace_letter)
print df

关于数据:

DatatableA,1
DatatableA,2
DatatableA,3
DatatableA,4
DatatableA,5
DatatableB,1
DatatableB,6
DatatableB,T
DatatableB,3
DatatableB,4
DatatableB,5
DatatableB,2
DatatableC,3
DatatableC,4
DatatableC,2
DatatableC,1
DatatableC,Q
DatatableC,5
DatatableC,T

希望产生以下内容

DatatableA,1
DatatableA,2
DatatableA,3
DatatableA,4
DatatableA,5
DatatableB,1
DatatableB,6
DatatableB,7
DatatableB,3
DatatableB,4
DatatableB,5
DatatableB,2
DatatableC,3
DatatableC,4
DatatableC,2
DatatableC,1
DatatableC,6
DatatableC,5
DatatableC,6

我收到了追溯:

Traceback (most recent call last):
  File "C:/test.py", line 11, in <module>
    df['col'] = df.groupby('datatable').transform(replace_letter)
  File "C:\Python27\lib\site-packages\pandas\core\groupby.py", line 1981, in transform
    res = path(group)
  File "C:\Python27\lib\site-packages\pandas\core\groupby.py", line 2006, in <lambda>
    slow_path = lambda group: group.apply(lambda x: func(x, *args, **kwargs), axis=self.axis)
  File "C:\Python27\lib\site-packages\pandas\core\frame.py", line 4416, in apply
    return self._apply_standard(f, axis)
  File "C:\Python27\lib\site-packages\pandas\core\frame.py", line 4491, in _apply_standard
    raise e
ValueError: ("invalid literal for int() with base 10: 'col'", u'occurred at index col')

我正在尝试用该表的下一个最高整数替换字母T或任何其他字母。第一个表没有错误,第二个表包含1个T,第三个表包含2个t。 有没有我正确使用的东西,但我更多地意思是使用pandas,因为这个库似乎对数据操作非常有用。

编辑1

拥有标题确实是一个问题,只需将header更改为=True即可。但是我仍然无法使用此代码来执行我想要的操作。

import pandas as pd

df = pd.read_csv('test.csv', sep=',', header=True, names=['datatabletest', 'col'])

def replace_letter(group):
    letters = group.isin(['T', 'Q'])              # select letters
    group[letters] = int(group[~letters].max()) + 1  # replace by next max
    return group

df["duplicate"] = df['col']
print df
df['col'] = df.groupby('datatabletest').transform(replace_letter)
print df

我希望复制该列,因此我有一份原件的副本,只更改了其中一列中的字母。你能看出我做错了吗?

1 个答案:

答案 0 :(得分:1)

我猜你的csv文件实际上包含一个标题,它的第一行是datatable,col。然后,当您指定header=None时,此标头将作为数据帧的第一行加载。您应该使用skiprows参数跳过标题,或者从删除header=None的文件中读取标题。

比较这两个例子:

>>> s = "DatatableA,1"
>>> df = pd.read_csv(StringIO(s),  sep=',', header=None, 
...          names=['datatable', 'col'])
>>> df['col'] = df.groupby('datatable').transform(replace_letter)
>>> df
    datatable  col
0  DatatableA    1    

但是

>>> df = pd.read_csv(StringIO('datatable,col\n'+s),  sep=',',
...          header=None, names=['datatable', 'col'])
>>> df['col'] = df.groupby('datatable').transform(replace_letter)
Traceback (most recent call last):
  ...
ValueError: ("invalid literal for int() with base 10: 'col'", u'occurred at index col')