python 获取嵌套长度可变的for循环中的特定字符串

y0u0uwnf  于 2022-12-02  发布在  Python
关注(0)|答案(1)|浏览(143)

我有以下电报导出JSON数据集:

import pandas as pd

df = pd.read_json("data/result.json")

>>>df.colums
Index(['name', 'type', 'id', 'messages'], dtype='object')

>>> type(df)
<class 'pandas.core.frame.DataFrame'>

df中,有一个 “messages” 列,该列具有以下输出:

>>> df["messages"]
0        {'id': -999713937, 'type': 'service', 'date': ...
1        {'id': -999713936, 'type': 'service', 'date': ...
2        {'id': -999713935, 'type': 'message', 'date': ...
3        {'id': -999713934, 'type': 'message', 'date': ...
4        {'id': -999713933, 'type': 'message', 'date': ...
                               ...                        
22377    {'id': 22102, 'type': 'message', 'date': '2022...
22378    {'id': 22103, 'type': 'message', 'date': '2022...
22379    {'id': 22104, 'type': 'message', 'date': '2022...
22380    {'id': 22105, 'type': 'message', 'date': '2022...
22381    {'id': 22106, 'type': 'message', 'date': '2022...
Name: messages, Length: 22382, dtype: object

在消息中,有一个名为 “text” 的特殊键,这就是我想要关注的问题。
单个文本:

>>> df["messages"][5]["text"]
'JAJAJAJAJAJAJA'
>>> df["messages"][22262]["text"]
'No creo'

但有时它是嵌套的。如下所示:

>>> df["messages"][22373]["text"]
['O ', {'type': 'mention', 'text': '@user87324'}, ' ta re meco']
>>> df["messages"][22189]["text"]
['The average married couple has sex roughly once a week. ', {'type': 'mention', 'text': '@googlefactss'}, ' ', {'type': 'hashtag', 'text': '#funfact'}]
>>> df["messages"][22345]["text"]
[{'type': 'mention', 'text': '@user817430'}]

在嵌套数据的情况下,如果我想抓取主文本,我可以执行以下操作:

>>> df["messages"][22373]["text"][0]
'O '
>>> df["messages"][22189]["text"][0]
'The average married couple has sex roughly once a week. '
>>>

从这里看,一切似乎都正常。然而,当我执行for循环时,问题出现了。如果我尝试以下操作:

for item in df["messages"]:
    tg_id = item.get("id", "None")
    tg_type = item.get("type", "None")
    tg_date = item.get("date", "None")
    tg_from = item.get("from", "None")
    tg_text = item.get("text", "None")
        
    print(tg_id, tg_from, tg_text)

输出示例如下:

21263 user3984 jajajajaja
21264 user837 ['Not sure', {'type': 'hashtag', 'text': '#confused'}]
21265 user3984 What time is it?✋

**我的问题:**如何扁平化行?我需要以下内容(并将其存储在数据框中):

21263 user3984 jajajajaja
21264 user837 Not sure
21265 user837 type: hashtag
21266 user837 text: #confused
21267 user3984 What time is it?✋

我试着这样检测“文本”类型:

for item in df["messages"]:
    tg_id = item.get("id", "None")
    tg_type = item.get("type", "None")
    tg_date = item.get("date", "None")
    tg_from = item.get("from", "None")
    tg_text = item.get("text", "None")

    if type(tg_text) == list:
        tg_text = tg_text[0]
    
    print(tg_id, tg_from, tg_text)

这样,我只抓取第一个文本,但我希望也能抓取其他字段或“展平”数据。
我也试探着:

for item in df["messages"]:
    tg_id = item.get("id", "None")
    tg_type = item.get("type", "None")
    tg_date = item.get("date", "None")
    tg_from = item.get("from", "None")
    tg_text = item.get("text", "None")

    if type(tg_text) == list:
        tg_text = tg_text[0]
        tg_second = tg_text[1]["text"]
    
    print(tg_id, tg_from, tg_text, tg_second)

但是没有运气,因为索引是可变的,消息的长度也是可变的。
此外,即使输出与我想要的解决方案不太接近,我也尝试过:
第一个
有什么想法吗?

vsaztqbk

vsaztqbk1#

只是为了分享一些想法来简化你的清单,

def flatlist(srclist):
    flatlist=[]
    if srclist: #check if srclist is not None
        for item in srclist:
            if(type(item) == str): #check if item is type of string
                flatlist.append(item)
            if(type(item) == dict): #check if item is type of dict
                for x in item:
                    flatlist.append(x + ' ' + item[x]) #combine key and value
    return flatlist

for item in df["messages"]:
    tg_text = item.get("text", "None")
    flat_list = flatlist(tg_text) # get the flattened list
    for tg in flat_list: # loop through the list and get the data you want
        tg_id = item.get("id", "None")
        tg_from = item.get("from", "None")
    
        print(tg_id, tg_from, tg)

相关问题