首页 > 解决方案 > 通过唯一值Python拆分充满字符串的Pandas数据框列

问题描述

我有一个数据框,其中包含一系列(列)字符串,这些字符串是空格分隔并连接在一起的。

数据框列如下所示:

[In]: df

[Out]:
 0   -- Generated 
 1   -- Formatting      
 2   -- Project1     
 3   -- Help        
 4   GRI                               -- Gen     
 5   S-P                               -- Gen
 6   COORD-SYS                         -- Gen
 7   COORD                             -- Gen
 8     318108.6945 6146696.895 1829.01714 318108.6945 6146696.895 
 9     1917.90444 334108.6945 6146696.895 1610.670059 334108.6945 
 10    6146696.895 1713.102355 350108.6945 6146696.895 1417.752346 350108.6945 
 11    NEF                             -- Gen
 12    318108.6945 6146696.895 1829.01714 318108.6945 6146696.895 
       2025.480832 326108.6945 6146696.895 1716.342492 326108.6945
 13    1917.90444 334108.6945 6146696.895 1610.670059 334108.6945 
       6146696.895 1813.845155 342108.6945 342108.6945
.
.

我想用不是数字的字符串来分隔这一列数据框,并取它们下面的所有数值,直到出现下一个非数值。

我需要的输出(例如 COORD 和 NEF 的类似输出)如下所示:

[In]: df_COORD 

[Out]:


 0     COORD       1            2           3           4            5         
 1     318108.6945 6146696.895  1829.01714  318108.6945 6146696.895  nan
 2     1917.90444  334108.6945  6146696.895 1610.670059 334108.6945  nan
 3     6146696.895 1713.102355  350108.6945 6146696.895 1417.752346 350108.6945 

我首先尝试使用类似的东西:

df_COORD = pd.DataFrame(df[0][7:11]).reset_index(drop=True)
df_COORD= df_COORD.rename(columns=df_COORD.iloc[0]).drop(0)
df_COORD= df_COORD[file_coord.iloc[0][0]].str.split(expand=True)

哪个有效,但我不想明确说明我想要哪些行;我想根据包含COORDNEF或任何其他list唯一字符串的列值进行分离,并在下面抓取数据,直到它到达另一个仅包含字母的字符串。

有什么办法可以做到这一点吗?

标签: pythonpython-3.xpandasdataframe

解决方案


据我了解,您需要标记相关行的块,然后使用 groupby 创建单独的数据框。根据您的描述,新的 DF 应该从包含非数字的行开始。假设您的原始 DF 具有默认名称的此列0

# flag the block based on the regex and cumsum()
# Warning: you might also consider scientific notation of numbers in regex
g1 = (df[0].str.contains('[^\d.\s+-]')).cumsum()

# initialize the dict for all sub-dataframes
dfs = {}

for g, d in df.groupby(g1):
    # having only 1 row in the sub-dataframue, then they are unrelated and skipped
    if d[0].size == 1: continue

    # do whatever you want to groups with rows containing numbers
    d = d[0].str.strip(' \t').str.split(expand=True)
    dname = d[0].iat[0]
    dfs[dname] = d.iloc[1:,:].rename(columns={0:dname})
    print(dfs[dname])

推荐阅读