我正在处理一个数据框架,它有一个'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
错误。请告诉我我做错了什么?
你可以这样做:
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'}]
我有同样的问题与'float' object is not iterable
时,试图使用函数,将迭代在for循环在每个单元格中的列表与应用方法,并将其分配给DataFrame作为新列。我将试着解释我的情况和我是如何解决的,也许它可以帮助任何人在未来。
我使用了许多列的DataFrame,但其中一个,让我们称之为'ColX'包含逗号分隔的字符串- f.单元格包含'bla,blueh,red,focus'。我需要分离这些字符串,然后遍历每个字符串以从源文档中找到它们的值。
我的第一个尝试是使它尽可能简单(更多的步骤),然后优化它(需要更少的步骤):
1。:创建了一个新列,'ColX2',其中包含一个拆分字符串列表
2。:定义了在for循环中遍历列表项的函数
3。:创建另一个新列,'ColX_cost',其中是来自源文档的每个价格的总和,通过对'ColX2'
应用定义函数所以我做了如下操作:
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
。
花了我很多时间,但我不想用不成功的尝试来打扰你,所以我将只描述最终有效的解决方案。
决定简化,我没有创建具有拆分字符串的列('ColX2'),我让函数对每一行执行此步骤。
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
的结果,但是臭名昭著的熊猫Setting with copy Warning
出现了。我对这个警告的解决方案是将数组函数create分配给新变量,然后将这个数组分配给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友好"的解决方案。