我正在从我的SEIM中提取一些JSON格式的日志(log)数据,并将其放入Pandas 数据框中.我能够轻松地将JSON转换为DataFrame中的多个列,但JSON中有一个"Message"字段,其中包含一个带引号的CSV,如下所示.

# dummy data
dfMyData = pd.DataFrame({"_raw": [\
            """{"timestamp":1691096387000,"message":"20230803 20:59:47,ip-123-123-123-123,mickey,321.321.321.321,111111,10673010,type,,'I am a, quoted, string, with commas,',0,,","logstream":"Blah1","loggroup":"group 1"}""",
            """{"timestamp":1691096386000,"message":"20230803 21:00:47,ip-456-456-456-456,mouse,654.654.654.654,222222,10673010,type,,'I am another quoted string',0,,","logstream":"Blah2","loggroup":"group 2"}"""
            ]})
# Column names for the _raw.message field that is generated.
MessageColumnNames =  ["Timestamp","dest_host","username","src_ip","port","number","type","who_knows","message_string","another_number","who_knows2","who_knows3"]
# Convert column to json object/dict
dfMyData['_raw'] = dfMyData['_raw'].map(json.loads)
# convert JSON into columns within the dataframe
dfMyData = pd.json_normalize(dfMyData.to_dict(orient='records'))

我以前见过使用str.split()对列进行拆分,然后将其连接回原始数据帧,但是str.split方法不处理CSV内的引号值.pd.read_csv可以正确处理引用的CSV,但我不知道如何将其应用于整个数据帧并将其输出扩展到新的数据帧列中.

此外,当我将dfMyData['_raw.message']分成新列时,我还想提供数据的列名列表,并使用这些名称创建新列.

有谁知道一种简单的方法,可以将数据帧中引用的CSV字符串拆分到数据帧中的新命名列中?

推荐答案

Update

实际上,您只需要将数据传递给CSV阅读器,而CSV阅读器又是适用于pandas.DataFrame的数据类型:

pd.DataFrame(csv.reader(dfMyData['_raw.message'], quotechar="'"), columns=columns)

Previous answer

我们可以try 将数据转换为CSV,并使用适当的参数将其读回:

import csv
from tempfile import TemporaryFile

seq = dfMyData.iloc[:,1]      # column of interest in the original data
columns = [*'ABCDEFGHIJKL']   # custom names of future data columns

with TemporaryFile() as file:

    seq.to_csv(
        file, 
        sep='\N{unit separator}',
        header=False,
        index=False,
        quoting=csv.QUOTE_NONE
    )

    file.seek(0)    # read data from the start

    df = pd.read_csv(
        file, 
        header=None,
        names=columns,
        quotechar="\'"
    )

print(df)

备注:

  • quoting=csv.QUOTE_NONE以避免每行末尾出现\"
  • sep='\N{unit separator}'以避免与逗号混淆
  • quotechar="\'"因行内有特定引语而回读时
  • 因为我们要转储一个没有索引的序列,所以'\N{unit separator}'分隔符永远不会出现在最终数据中

转换后的数据:

output

Python相关问答推荐

在有限数量的唯一字母的长字符串中,找到包含重复不超过k次的所有唯一字母的最长子字符串

Django关于UniqueBindition的更新

将numpy数组与空数组相加

Python如何让代码在一个程序中工作而不在其他程序中工作

Tkinter滑动条标签.我不确定如何删除滑动块标签或更改其文本

如何修复使用turtle和tkinter制作的绘画应用程序的撤销功能

symy.分段使用numpy数组

Pandas 在时间序列中设定频率

Python -Polars库中的滚动索引?

如何从FDaGrid实例中删除某些函数?

多处理代码在while循环中不工作

带条件计算最小值

优化pytorch函数以消除for循环

根据二元组列表在pandas中创建新列

如何过滤包含2个指定子字符串的收件箱列名?

如何在solve()之后获得症状上的等式的值

梯度下降:简化要素集的运行时间比原始要素集长

在ubuntu上安装dlib时出错

字符串合并语法在哪里记录

Django admin Csrf令牌未设置