数据框单元格中的Pandas迭代列表

shstlldc  于 2023-04-04  发布在  其他
关注(0)|答案(2)|浏览(121)

我正在处理一个dataframe,它有一个'books'列,每个单元格中都有一个书籍列表。这是'books'列中的一个示例单元格内容:

["{"book_name":"abc","book_size":"43","requestor":"97457239247","comments":"this is a comment"}",
"{"book_name":"def","book_size":"453","requestor":"27657899462","comments":"this is a comment"}"]

我尝试循环遍历单元格以找到具有特定请求者的图书,然后获取整个图书对象并将其粘贴到新列中。
我的代码:

def find_hipri_book(books):
        for book in books:
            if '27657899462' in book:
                return book
   
    df['hipri_book'] = df['books'].apply(find_hipri_book)

我也试过:

def find_hipri_book(row):
    for book in row['books']:
        if '27657899462' in book:
            return book

df['hipri_book'] = df.apply(find_hipri_book, axis=1)

上面两个都给予'float' object is not iterable错误。请告诉我我做错了什么?

s5a0g9ez

s5a0g9ez1#

您可以:

a = [{"book_name":"abc","book_size":"43","requestor":"97457239247","comments":"this is a comment"},
{"book_name":"def","book_size":"453","requestor":"27657899462","comments":"this is a comment"}]

pd.DataFrame(a).loc[lambda x:x.requestor == '27657899462'].to_dict('records')

 [{'book_name': 'def',
      'book_size': '453',
      'requestor': '27657899462',
      'comments': 'this is a comment'}]

或者甚至:

pd.DataFrame(a).query("requestor == '27657899462'").to_dict('records')

[{'book_name': 'def',
  'book_size': '453',
  'requestor': '27657899462',
  'comments': 'this is a comment'}]

如果这些是字符串而不是字典,则必须将它们转换为字典,然后剩下的就可以了。

b = ['{"book_name":"abc","book_size":"43","requestor":"97457239247","comments":"this is a comment"}',
'{"book_name":"def","book_size":"453","requestor":"27657899462","comments":"this is a comment"}']

pd.DataFrame(pd.Series(b).apply(eval).tolist()).query("requestor == '27657899462'").to_dict('records')

[{'book_name': 'def',
  'book_size': '453',
  'requestor': '27657899462',
  'comments': 'this is a comment'}]
bvuwiixz

bvuwiixz2#

我在'float' object is not iterable中遇到了同样的问题,当我试图使用函数时,该函数将使用apply方法在每个单元格中的列表上迭代for循环,并将其作为新列分配给DataFrame。我将尝试解释我的情况以及我如何解决它,也许它可以帮助任何人在未来。
我使用了许多列的DataFrame,但其中一个,让我们称之为 'ColX' 包含由逗号分隔的字符串-例如cell包含 'bla,blueh,red,focus'。我需要分隔这些字符串,然后迭代每个字符串以从源文档中找到它们的值。
我的第一次尝试是尽可能简单(更多步骤),然后优化它(需要更少的步骤):
1.:创建了一个新列 'ColX 2',其中包含拆分字符串的列表
2.:定义函数来迭代for循环中的列表项
3.:创建另一个新列 'ColX_cost',其中是源文档中每个价格的总和,方法是对 'ColX 2' 应用定义的函数。
所以我做了以下工作:

df['ColX2'] = df['ColX'].str.split(',')

def find_value_by_itteration(row):
    sum = 0
    for part in row['ColX2']:
        sum += sourcedoc.loc[part, 'price']
    return sum

df['ColX_cost'] = df.apply(find_value_by_itteration, axis=1)

我有'float' object is not iterable
花了我很多时间,但我不想打扰你与不成功的尝试来解决这个问题,所以我将只描述最终的解决方案,工程。
决定简化,我没有创建拆分字符串的列('ColX 2'),我让我的函数为每一行做这一步。

def find_value_by_itteration2(row):
    sum = 0
    parts = row['ColX'].str.split(',')
    for part in parts:
        sum += sourcedoc.loc[part, 'price']
    return sum

df['ColX_cost'] = df.apply(find_value_by_itteration2, axis=1)

使用这个,我能够在没有'float' object is not iterable的情况下得到结果,但是出现了臭名昭著的PandasSetting with copy Warning。我对这个警告的解决方案是将数组函数创建的值分配给新变量,然后将这个数组作为新列分配给DataFrame。最后,代码的所需部分看起来:

def find_value_by_itteration2(row):
    sum = 0
    parts = row['ColX'].str.split(',')
    for part in parts:
        sum += sourcedoc.loc[part, 'price']
    return sum

arr = df.apply(find_value_by_itteration2, axis=1)
df = df.assign(ColX_cost=arr)

现在它可以完美地工作,因为我需要,但我很肯定有人可以找到'Python友好'的解决方案。

相关问题