[英]String split a row in a table in every nth space
我有這個數據集,我試圖在其中拆分OrtoB列,以允許我的數據在多對多交互中從A到B進行組織。
示例數據集
new_name Score OrtoA OrtoB
0 1 3064 g2797.t1 1.000 YHR165C 1.000
1 2 2820 g2375.t1 1.000 YJL130C 1.000
2 3 2711 g1023.t1 1.000 YLR106C 1.000
3 4 2710 g15922.t1 1.000 YNR016C 1.000
4 5 2568 g3549.t1 1.000 YDL171C 1.000
5 6 2494 g10464.t1 1.000 YOR153W 1.000 YDR406W 0.585 YOR328W 0.454
6 7 2402 g15604.t1 1.000 YGR032W 1.000 YLR342W 0.679
到目前為止,我已經可以使用python中的以下代碼來拆分字符串,並按照之前回答過的熊貓提供的示例進行操作:如何將一列中的文本拆分成多行? 。
z = pd.read_table("table.augustus",header=0)
col_name =z.columns[0]
z = z.rename(columns = {col_name:'new_name'}
z['OrtoB'].str.split(" ").apply(Series,1).stack()
但是,只有在我要拆分的空間只有一個時,它才起作用。 我正在尋找的是在每個第二空間進行分割以獲取如下結果的幫助。
所需結果
OrtoA OrtoB
g2797.t1 1 YHR165C 1
g2375.t1 1 YJL130C 1
g1023.t1 1 YLR106C 1
g15922.t1 1 YNR016C 1
g3549.t1 1 YDL171C 1
g10464.t1 1 YOR153W 1
g10464.t1 1 YDR406W 0.585
g10464.t1 1 YOR328W 0.454
g15604.t1 1 YGR032W 1
g15604.t1 1 YLR342W 0.679
如果某些所需的列在內部有空格,則合並拆分后所需的內容。 您也可以使用不帶任何參數的split()代替split(“”)。 即使使用制表符或其他空格也可以工作。
def concat_pairs(l)
return [ "%s %s" % (l[i], l[i+1] for i, x in enumerate(l) if not i % 2]
concat_pairs( z['OrtoB'].str ).apply( ...
重新拆分一個更簡單的修補程序
re.split('[a-f]+ [a-f]+', z['OrtoB'].str).apply(...
您可以使用:
#column into lists
orto = z['OrtoB'].str.split()
#remove all empty lists
orto = orto[orto.astype(bool)]
#get lengths of lists, but floor divide by 2 because pairs
lens = orto.str.len() // 2
#explode nested lists to array
orto2 = np.concatenate(orto.values)
#repeat index to explode
idx = z.index.repeat(lens)
#create DataFrame and join both column together
s = pd.DataFrame(orto2.reshape(-1,2), index=idx).apply(' '.join, axis=1).rename('OrtoB')
#remove original column and join s
z = z.drop('OrtoB', axis=1).join(s).reset_index(drop=True)
print (z)
new_name Score OrtoA OrtoB
0 1 3064 g2797.t1 1.000 YHR165C 1.000
1 2 2820 g2375.t1 1.000 YJL130C 1.000
2 3 2711 g1023.t1 1.000 YLR106C 1.000
3 4 2710 g15922.t1 1.000 YNR016C 1.000
4 5 2568 g3549.t1 1.000 YDL171C 1.000
5 6 2494 g10464.t1 1.000 YOR153W 1.000
6 6 2494 g10464.t1 1.000 YDR406W 0.585
7 6 2494 g10464.t1 1.000 YOR328W 0.454
8 7 2402 g15604.t1 1.000 YGR032W 1.000
9 7 2402 g15604.t1 1.000 YLR342W 0.679
這是我的解決方案:
# split `OrtoB` into lists
df['OrtoB'] = df['OrtoB'].str.findall(r'([A-Z\d]{6,}\s[\d\.]+)')
# now we can use the same technique as in: http://stackoverflow.com/a/40449726/5741205
def split_list_in_cols_to_rows(df, lst_cols, fill_value=''):
# make sure `lst_cols` is a list
if lst_cols and not isinstance(lst_cols, list):
lst_cols = [lst_cols]
# all columns except `lst_cols`
idx_cols = df.columns.difference(lst_cols)
# calculate lengths of lists
lens = df[lst_cols[0]].str.len()
return pd.DataFrame({
col:np.repeat(df[col].values, df[lst_cols[0]].str.len())
for col in idx_cols
}).assign(**{col:np.concatenate(df[col].values) for col in lst_cols}) \
.append(df.loc[lens==0, idx_cols]).fillna(fill_value) \
.loc[:, df.columns]
結果:
In [30]: %paste
df['OrtoB'] = df['OrtoB'].str.findall(r'([A-Z\d]{6,}\s[\d\.]+)')
new = split_list_in_cols_to_rows(df, 'OrtoB')
new
## -- End pasted text --
Out[30]:
new_name Score OrtoA OrtoB
0 1 3064 g2797.t1 1.000 YHR165C 1.000
1 2 2820 g2375.t1 1.000 YJL130C 1.000
2 3 2711 g1023.t1 1.000 YLR106C 1.000
3 4 2710 g15922.t1 1.000 YNR016C 1.000
4 5 2568 g3549.t1 1.000 YDL171C 1.000
5 6 2494 g10464.t1 1.000 YOR153W 1.000
6 6 2494 g10464.t1 1.000 YDR406W 0.585
7 6 2494 g10464.t1 1.000 YOR328W 0.454
8 7 2402 g15604.t1 1.000 YGR032W 1.000
9 7 2402 g15604.t1 1.000 YLR342W 0.679
根據您引用的答案,我有一些有效的方法:
import pandas as pd
s = df.OrtoB.str.split(' ').apply(pd.Series, 1).stack()
s.index = s.index.droplevel(-1)
#merge 2 consecutive OrtoB values in to 1 and separated by ' '.
s = pd.DataFrame(data = s.values.reshape(-1,2),index=s.index[::2]).apply(lambda x: ' '.join(x), axis=1)
del(df['OrtoB'])
s.name = 'OrtoB'
df.join(s)
Out[148]:
new_name Score OrtoA OrtoB
0 1 3064 g2797.t1 1.000 YHR165C 1.000
1 2 2820 g2375.t1 1.000 YJL130C 1.000
2 3 2711 g1023.t1 1.000 YLR106C 1.000
3 4 2710 g15922.t1 1.000 YNR016C 1.000
4 5 2568 g3549.t1 1.000 YDL171C 1.000
5 6 2494 g10464.t1 1.000 YOR153W 1.000
5 6 2494 g10464.t1 1.000 YDR406W 0.585
5 6 2494 g10464.t1 1.000 YOR328W 0.454
6 7 2402 g15604.t1 1.000 YGR032W 1.000
6 7 2402 g15604.t1 1.000 YLR342W 0.679
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.