【问题标题】:Formatting data in pandas在熊猫中格式化数据
【发布时间】:2014-01-02 12:39:03
【问题描述】:

我尝试运行代码:

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 x 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

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

【问题讨论】:

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


    【解决方案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')
    

    【讨论】:

    • 我已经编辑了我的代码,以显示我遇到的次要错误。
    • @AEA 对于次要错误,您不应该编辑原始问题而是开始一个新问题,这样您每个问题和答案都保留一个问题,使其更便于进一步参考。对于您的第二个问题,您可以使用df['dup'] = df.groupby('datatabletest')['col'].transform(replace_letter),但由于上述原因,我不想将其添加到答案中。
    • 谢谢 alko,我确实考虑过,但我认为如果我这样做可能会被标记为重复。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2019-03-17
    • 2018-03-28
    • 2021-10-04
    • 1970-01-01
    • 2018-10-23
    • 2017-10-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多