微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

从行列表逐行生成DataFrame

如何解决从行列表逐行生成DataFrame

我有一个高度不规则的文本文件,试图从中创建Pandas DataFrame。经过大量的处理(删除不规则,行,可变标题等)之后,我到达了需要根据需要解析每行的地步,但是在将其转换为DataFrame时遇到了麻烦。请注意,每行的长度是可变的,每行中的元素数可以不同。

输入

15.2'   4.3'  16.9'   4.0',GVW kips= 70.6,9.5,14.5,14.1,15.8,16.7
3.2'   10.0',GVW kips= 30.2,11.3,12.0

所需的输出DataFrame (请注意,我必须删除'个字符,并且GWV kips=之后的第一个数字不包含在DataFrame中)

S1    S2    S3    S4    S5   W1    W2    W3    W4    W5    W6
15.2  4.3   16.9  4.0   Nan  9.5   14.5  14.1  15.8  16.7  Nan
3.2   10.0  Nan   Nan   Nan  30.2  9.5   11.3  12.0  Nan   Nan

解析一行

my_string = r"15.2'   4.3'  16.9'   4.0',16.7"
my_list = my_string.split("'") #get rid of " ' " characters
my_list = [l.split(',') for l in ','.join(my_list).split(' GVW kips= ')] # split the list into two parts one for "S" columns one for "W" columns
my_list = [list(filter(None,lst)) for lst in my_list] # get rid of '' empty strings
my_list = [[float(j) for j in i] for i in my_list] # convert everything to floats
my_list[1].pop(0) # get rid of first element after GVW kips=

这给了我以下两个列表:

[[15.2,4.3,16.9,4.0],[9.5,16.7]]

这时,当我将这两个列表转换时,我陷入了困境:第一个列表将S1列转换为S5,另一个列表将W1列转换为W6缺少元素的DataFrame应该显示为NaN。到目前为止,该操作仅适用于一行。对于超过1,000,000行,我需要这样做。

我想我可以创建名为W1W6S1S5的系列列表,然后逐行附加值。当所有系列准备就绪时,将所有内容转换为DataFrame。问题是实际上我有30 W和29 S列,这将要求我在整个运行过程中维护59个列表,这听起来没有意义...

是否有更好的方法来构建DataFrame,方法是逐行读取文本文件,并针对每行使用输出两个列表,其中每行的长度可能不同?

谢谢!

解决方法

这有效

  1. 了解我如何构建字典的最简单方法之一就是熟悉数据框to_dict()格式的各种选项
  2. 我真的看到了一个简单的模式,字符串分为两个部分,分别由常量字符串分隔。因此,请使用re来获取两个部分
  3. 使用zip进行分类并简化构建dict密钥
import re,io
import pandas as pd
import numpy as np
    
inp = """15.2'   4.3'  16.9'   4.0',GVW kips= 70.6,9.5,14.5,14.1,15.8,16.7
3.2'   10.0',GVW kips= 30.2,11.3,12.0"""

# remove unwanted spaces and quotes
inp = inp.replace("'","").replace(",","")

d = {r:{f"{k}{c+1}":vv
  # tokenise into S & W with "GVW kips=" being delimter
  for k,v in zip(["S","W"],re.findall("^([\d. ]*)GVW kips= ([\d. ]*)$",s)[0])
  # use re.split so multiple spaces are treated as one
  for c,vv in enumerate(re.split("[ ]+",str(v)))
 } 
 for r,s in enumerate(inp.split("\n"))}

pd.DataFrame(d).T.replace({"":np.nan})

输出

   S1    S2    S3   S4  S5    W1   W2    W3    W4    W5    W6
 15.2   4.3  16.9  4.0 NaN  70.6  9.5  14.5  14.1  15.8  16.7
  3.2  10.0   NaN  NaN NaN  30.2  9.5  11.3  12.0   NaN   NaN
,

添加NaN以满足所需的列数。在循环过程中完成一百万行后,它将转换为数据帧。这种方法将更快,更高效。

s = 5
for i in range(s - len(my_list[0])):
    my_list[0].append(np.NaN)

w = 6
for i in range(w - len(my_list[1])):
    my_list[1].append(np.NaN)

new = pd.DataFrame(index=[],columns=[])
new = pd.concat([new,pd.Series(sum(my_list,[])).to_frame().T],axis=0,ignore_index=True)
cols = ['S1','S2','S3','S4','S5','W1','W2','W3','W4','W5','W6']
new.columns = cols
new
S1  S2  S3  S4  S5  W1  W2  W3  W4  W5  W6
0   15.2    4.3 16.9    4.0 NaN 9.5 14.5    14.1    15.8    16.7    NaN

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。