【问题标题】:Numbers with hyphens or strings of numbers with hyphens带连字符的数字或带连字符的数字串
【发布时间】:2014-01-18 17:19:05
【问题描述】:

我需要制作一个带有连字符数字的列的 pandas DataFrame。我能想到的唯一方法是使用字符串。这一切都很好,直到我需要对它们进行分类以在重新组合后让它们恢复正常。问题是字符串排序如下:

['100-200','1000-1100','1100-1200','200-300']

这显然不是我想要的排序方式。我希望它按数字排序。我怎样才能让它工作?我愿意改变任何事情。将带连字符的字符串保留为整数或浮点数是最好的,但我不确定如何做到这一点。

【问题讨论】:

    标签: python sorting hyphen


    【解决方案1】:

    你可以试试这样的:

    >>> t = ['100-200','1000-1100','1100-1200','200-300']
    >>> t.sort(key=lambda x: [int(y) for y in x.split('-')])
    >>> t
    ['100-200', '200-300', '1000-1100', '1100-1200']
    

    这将允许您对整数进行排序,如果存在连字符,它将首先按键列表中的第一个整数排序,然后按第二个整数排序。如果不存在连字符,您将仅对字符串的整数等值进行排序:

    >>> t = ['100-200','1000-1100','1100-1200','200-300', '100']
    >>> t.sort(key=lambda x: [int(y) for y in x.split('-')])
    >>> t
    ['100', '100-200', '200-300', '1000-1100', '1100-1200']
    

    如果您在任何字符串中有任何 float 等效项,只需将 int 更改为 float,如下所示:

    >>> t = ['100-200.3','1000.5-1100','1100.76-1200','200-300.75', '100.35']
    >>> t.sort(key=lambda x: [float(y) for y in x.split('-')])
    >>> t
    ['100-200.3', '100.35', '200-300.75', '1000.5-1100', '1100.76-1200']
    

    【讨论】:

      【解决方案2】:

      您可以使用sorted 为索引构造新的排序,然后使用df.take 执行排序(重新排序):

      import pandas as pd
      
      df = pd.DataFrame({'foo':['100-200','1000-1100','1100-1200','200-300']})
      order = sorted(range(len(df)),
                     key=lambda idx: map(int, df.ix[idx, 'foo'].split('-')))
      df = df.take(order)
      print(df)
      

      产量

               foo
      0    100-200
      3    200-300
      1  1000-1100
      2  1100-1200
      

      这类似于@275365 的解决方案,但请注意排序是在range(len(df)) 上完成的,而不是在字符串上。这些字符串仅在key 参数中使用,以确定range(len(df)) 应重新排列的顺序。


      如果 DataFrame 很小,使用 sorted 可以正常工作。当DataFrame 大小适中时(例如,我的机器上有几百行),您可以通过使用numpy.argsort 来获得更好的性能:

      import pandas as pd
      import numpy as np
      
      df = pd.DataFrame({'foo':['100-200','1000-1100','1100-1200','200-300']*100})
      
      arr = df['foo'].map(lambda item: map(int, item.split('-'))).values
      order = np.argsort(arr)
      df = df.take(order)
      

      或者,您可以将字符串列拆分为两个整数值列,然后使用df.sort

      import pandas as pd
      
      df = pd.DataFrame({'foo':['100-200','1000-1100','1100-1200','200-300']})
      
      df[['start', 'end']] = df['foo'].apply(lambda val: pd.Series(map(int, val.split('-'))))
      df.sort(['start', 'end'], inplace=True)
      print(df)
      

      产量

               foo  start   end
      0    100-200    100   200
      3    200-300    200   300
      1  1000-1100   1000  1100
      2  1100-1200   1100  1200
      

      【讨论】:

      • 使用带有 numpy 的解决方案似乎对我有用。出于某种原因,使用 sort 或 sorted 会给我一个带有无效关键字“key”的 TypeError。新问题是我需要它先按一列排序,然后按连字符列排序,而不是弄乱第一列。
      • 最终使用了您的最后一个解决方案,然后在排序后删除开始和结束列。这使我可以对所有 3 列进行排序。谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-09-01
      • 2018-03-09
      • 2010-12-30
      • 1970-01-01
      • 2015-09-14
      • 1970-01-01
      • 2020-06-04
      相关资源
      最近更新 更多