2016-07-31 19 views
2

我採取在用戶提供的輸入字符串數組,可以如下所示:跟蹤項的陣列與分隔符蟒

x=[100.0,150.0,200.0:300.0:10.0,300.0,350.0:400.0:10.0,500.0,600.0:700.0:10.0,800.0,900.0] 

由於這些是用戶提供的列表,所述間隔片的順序[例如,200.0:300.0:10.0]可以變化,如同沒有切片的單個條目一樣。

然後我分裂的「:」分隔符,這樣我就可以從浮到字符串中使用numpy.r_隱蔽到後來我得到以下列表:

x_arr=[100.0,150.0,200.0,300.0,10.0,300.0,350.0,400.0,10.0,500.0,600.0,700.0,10.0,800.0,900.0] 

我想保持賽道上的原指數「:」分隔符存在,以及這裏的「:」分隔符缺席這樣我就可以重建原始數組以下列方式的一系列花車:

np.r_[100.0, 150.0, slice(200.0,300.0,10.0), 300, slice(350.0,400.0,10.0), 500.0, slice(600,700,10),800,900] 

問題是如何跟蹤指數從原始數組到新數組的變化支架方式。我很感激任何關於如何用隨機用戶提供的輸入來實現這一點的想法。

這是我想過接近的一種方式:

我劈在原數組「」地發現,缺少的元素

x_no_colon=re.split((','),x) 
xh=[] 
for ind in x_no_colon: 
    inds_wo_colon=re.findall(":",ind) 
    xh.append(inds_wo_colon) 

使用上述其中:‘:’分隔符例如將返回以下:

xh=[[],[],[":",":"],[],[":",":"],[],[":",":"],[],[]] 

然後我可以找出指數沒有冒號以下方式:

x_wo_colons = [item for item in range(len(xh)) if xh[item] == []] 

這將返回:

x_wo_colons=[0,1,3,6,8,9] 

然後我找到了指數:分隔符使用上的一組分裂 '' ':':

colon_arr=re.split('(:)',x) 
prelim_x_with_colon=[item for item in range(len(colon_arr)) if colon_arr[item] == ':'] 

x_w_colon=[] 
for i in prelim_x_with_colon: 
    if i == 1 and colon_arr[1] != ':': 
     x_w_colon.append(i) 
    elif i == 1 and colon_arr[1] == ':': 
     x_w_colon.append(i-1) 
    else: 
     x_w_colon_append(i-1) 

隨着指數的其中一個列表冒號存在並且不存在,唯一要做的就是從列表w /冒號中刪除沒有冒號的索引。我在這裏找到的問題是,每次更改列表都很難獲得正確的索引。這可能是因爲我的方法很複雜,我使用兩個不同的數組作爲不同的列表。

問題是如何以一致的方式跟蹤從原始數組到索引的更改。我很感激任何關於如何用隨機用戶提供的輸入來實現這一點的想法。

在此先感謝!

+0

@Moses Koledoye這裏是更新的問題 – user1332577

回答

1

您是否試圖將此輸入字符串/列表轉換爲數字列表/數組,並考慮到某些項目看起來像切片?

這是我對你的字符串的實驗(減去[])。我會留下很多試驗和錯誤。這可能是有益的。

In [957]: txt='100.0,150.0,200.0:300.0:10.0,300.0,350.0:400.0:10.0,500.0,600.0:700.0:10.0,800.0,900.0' 

我假定,是主分隔符,:次級

In [958]: txt.split(',') 
Out[958]: 
['100.0', 
'150.0', 
'200.0:300.0:10.0', 
'300.0', 
'350.0:400.0:10.0', 
'500.0', 
'600.0:700.0:10.0', 
'800.0', 
'900.0'] 

定義一個函數來處理這些項目中的一個:

In [960]: def foo(astr): 
    ...:  items=astr.split(':') 
    ...:  if len(items)==1: 
    ...:   return float(items[0]) 
    ...:  else: 
    ...:   return slice(*[float(i) for i in items]) 
    ...:  
In [961]: [foo(s) for s in txt.split(',')] 
Out[961]: 
[100.0, 
150.0, 
slice(200.0, 300.0, 10.0), 
300.0, 
slice(350.0, 400.0, 10.0), 
500.0, 
slice(600.0, 700.0, 10.0), 
800.0, 
900.0] 

In [962]: np.r_[_] 
Out[962]: 
array([100.0, 150.0, slice(200.0, 300.0, 10.0), 300.0, 
     slice(350.0, 400.0, 10.0), 500.0, slice(600.0, 700.0, 10.0), 800.0, 
     900.0], dtype=object) 

它創建切片等我預期,但np.r_不接受字面切片;它需要:語法。實際上它是Python解釋器,它將[a:b:c]轉換爲slice(a,b,c)對象。似乎我們最近解決了這個問題。我們直接跳到arange(因爲np.r_翻譯了slicesarangelinspace反正)。

In [963]: def foo(astr): 
    ...:  items=astr.split(':') 
    ...:  if len(items)==1: 
    ...:   return float(items[0]) 
    ...:  else: 
    ...:   return np.arange(*[float(i) for i in items]) 

In [964]: [foo(s) for s in txt.split(',')] 
Out[964]: 
[100.0, 
150.0, 
array([ 200., 210., 220., 230., 240., 250., 260., 270., 280., 290.]), 
300.0, 
array([ 350., 360., 370., 380., 390.]), 
500.0, 
array([ 600., 610., 620., 630., 640., 650., 660., 670., 680., 690.]), 
800.0, 
900.0] 

In [965]: np.concatenate(_) 
... 
ValueError: zero-dimensional arrays cannot be concatenated 

糟糕,concatenate不喜歡單個數字;

In [966]: def foo(astr): 
    ...:  items=astr.split(':') 
    ...:  if len(items)==1: 
    ...:   return [float(items[0])] 
    ...:  else: 
    ...:   return np.arange(*[float(i) for i in items]) 

In [967]: [foo(s) for s in txt.split(',')] 
Out[967]: 
[[100.0], 
[150.0], 
array([ 200., 210., 220., 230., 240., 250., 260., 270., 280., 290.]), 
[300.0], 
array([ 350., 360., 370., 380., 390.]), 
[500.0], 
array([ 600., 610., 620., 630., 640., 650., 660., 670., 680., 690.]), 
[800.0], 
[900.0]] 

In [968]: np.concatenate(_) 
Out[968]: 
array([ 100., 150., 200., 210., 220., 230., 240., 250., 260., 
     270., 280., 290., 300., 350., 360., 370., 380., 390., 
     500., 600., 610., 620., 630., 640., 650., 660., 670., 
     680., 690., 800., 900.]) 

看起來不錯。

=======================

在最近的答案,我確實發現通過文字slice對象r_的一種方式,在元組。

In [969]: def foo1(astr): 
    ...:  items=astr.split(':') 
    ...:  if len(items)==1: 
    ...:   return float(items[0]) 
    ...:  else: 
    ...:   return slice(*[float(i) for i in items]) 
... 
In [971]: tuple([foo1(s) for s in txt.split(',')]) 
Out[971]: 
(100.0, 
150.0, 
slice(200.0, 300.0, 10.0), 
300.0, 
slice(350.0, 400.0, 10.0), 
500.0, 
slice(600.0, 700.0, 10.0), 
800.0, 
900.0) 

In [972]: np.r_[tuple([foo1(s) for s in txt.split(',')])] 
Out[972]: 
array([ 100., 150., 200., 210., 220., 230., 240., 250., 260., 
     270., 280., 290., 300., 350., 360., 370., 380., 390., 
     500., 600., 610., 620., 630., 640., 650., 660., 670., 
     680., 690., 800., 900.]) 
+0

讓np.r_接受文字切片我做了np.concatenate([np.r_ [i] for i in x])(如果x是數組)。謝謝!該功能是一個非常聰明的方式! – user1332577

+0

你知道如果使用np.arange比僅使用slice功能更快嗎?或者他們在你的經歷中相當相似​​? – user1332577

+0

'r_'使用'arange'將'slice'轉換爲數字。看看'lib/index_tricks.py'中的代碼 – hpaulj

1

你說輸入數組是一個字符串,所以(使用實施例):

x = x[1:-1].split(',') 
x = ([float(y) for y in elt.split(':')] for elt in x) 

x = '[100.0,150.0,200.0:300.0:10.0,300.0,350.0:400.0:10.0,500.0,600.0:700.0:10.0,800.0,900.0]' 

然後,我們通過,通過:分裂x然後將元件我把x變成了發電機,但現在基本上是

[[100.0], [150.0], [200.0, 300.0, 10.0], [300.0], [350.0, 400.0, 10.0], [500.0], [600.0, 700.0, 10.0], [800.0], [900.0]] 

在這一點上,我不知道如何創建要與numpy.r_數組,但我認爲同樣的目標可以通過

x = (y if len(y) == 1 else np.arange(*y) for y in x) 
result = np.hstack(x) 

這裏np.arange實現是numpy的的range這需要float參數,和np.hstack,根據其文檔字符串「按照順序堆疊數組(按列)」。

+0

哇,這個工程太棒了!我在一堆隨機輸入上測試了它,它似乎每次都完美地執行這個技巧。 – user1332577