【问题标题】:Python Sorting elements in a List in pandas DataframePython对熊猫数据框中列表中的元素进行排序
【发布时间】:2021-12-19 16:00:46
【问题描述】:

我的公司要求我将数据作为列表上传,并附上报价,这不是最好的,但就是这样。例如,如果我有 2 英寸和 3 英寸的数据,我必须将其上传为 ["2 in", "3 in"]。

当我尝试对列表中每一行的元素进行排序时,我得到:[1, 2, , ", ", [, ], o, z] 它对每个单独的字母和数字进行排序

Example of the DF I am trying to sort:
d = {'col1': ['["3 oz","1 oz","2 oz"]', '["1.2 in","1 in","1.3 in"]', '["10 in","22 in","3.4 in"]']}
df = pd.DataFrame(data=d)

我尝试过的:

def sorted_alphanumeric(data):
    convert = lambda text: int(text) if text.isdigit() else text.lower()
    alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ] 
    return sorted(data, key=alphanum_key)
df['col1'].apply(lambda x: sorted_alphanumeric((x)))

and 

from natsort import natsorted
df['col1'].apply(lambda x: natsorted(x))

and

df['col1'].apply(lambda x: sorted(x))

我确信在盯着这个 2 天后我想念它的一些简单的东西,但如果你对如何解决它有任何想法,我将不胜感激。

【问题讨论】:

    标签: python pandas list dataframe sorting


    【解决方案1】:

    因为你有字符串,你首先需要把数据分成块。为此删除前 2 个和后 2 个字符 [""],然后拆分 "," 以获取数据列表。

    这是使用 apply 的一种方式:

    from natsort import natsorted
    (df['col1'].str[2:-2].str.split('","')
               .apply(lambda x: '["'+'","'.join(natsorted(x))+'"]')
    )
    

    输出(作为一个系列):

    0        ["1 oz","2 oz","3 oz"]
    1    ["1 in","1.2 in","1.3 in"]
    2    ["3.4 in","10 in","22 in"]
    Name: col1, dtype: object
    

    为了明确起见,这些项目是字符串:'["1 oz","2 oz","3 oz"]'

    注意。这纯粹是先按数字排序,然后按字母数字字符串的单位排序,它确实考虑单位的含义

    【讨论】:

      【解决方案2】:
      from natsort import natsorted
      df['col1'] = df['col1'].apply(lambda x: natsorted(eval(x)))
      print(df)
      
                           col1
      0      [1 oz, 2 oz, 3 oz]
      1  [1 in, 1.2 in, 1.3 in]
      2  [3.4 in, 10 in, 22 in]
      

      【讨论】:

        【解决方案3】:

        您可以使用eval 来评估字符串:

        df['col1'].apply(lambda x: sorted(eval(x)))
        

        但是,通过这种方式,列表按字典顺序排序,因此如果您希望它们按其中包含的数字排序,则必须编写更复杂的函数。

        【讨论】:

          【解决方案4】:

          你可以使用ast.literal_eval然后按如下排序:

          (Why using literal_eval and not using eval)

          >>> from ast import literal_eval
          >>> df['col1'] = df['col1'].apply(lambda x: sorted(literal_eval(x)))
          >>> df
                     col1
          0      [1 oz, 2 oz, 3 oz]
          1      [1 in, 1.2 in, 1.3 in]
          2      [10 in, 22 in, 3.4 in]
          
          

          【讨论】:

            猜你喜欢
            • 2014-12-29
            • 1970-01-01
            • 2014-09-19
            • 1970-01-01
            • 1970-01-01
            • 2019-04-12
            • 2020-11-06
            • 2016-10-13
            相关资源
            最近更新 更多