2014-03-26 37 views
0

我一直在試圖解決這個問題一段時間,我會感激推向正確的方向。Matlab:計數直到總和等於360>插入事件1,接下來的360>插入事件2等

我有一個叫Turn的矩陣。該矩陣包含1列數據,大約在10000到15000行之間(可變)。我喜歡做的事情如下: 從第1行開始,並添加第2行,第3行等值直到sum == 360。當sum == 360在第2列中插入特定行'事件1'時。 從下一行開始計數('事件1'之後)直到sum == 360。當sum == 360在第2列的特定行'事件2'處插入時。等

所以我基本上想分組我的數據在分區總和== 360 這些將被稱爲事件。

sum == 360對我來說很重要的行號(每一行都是一個時間點,所以它會告訴我一個事件的持續時間)。我希望把這些行號在一個新的矩陣,其中在第1行:rownr事件發生1,第2行:rownr事件發生2等

回答

0

給定的列向量x,比方說,

x = randi(100,10,1) 

下面會給你的第一行的索引,其中,累積和關閉該行的所有上述項目加起來是360:

i = max(find(cumsum(x) <= 360)) 

然後,你將不得不使用索引來查找下一組的累積總和可以達到360,如

offset = max(find(cumsum(x(i+1:end)) <= 360)) 
i_new = i + offset 

您可能需要將+ 1/-1添加到偏移量和索引。

>> x = randi(100,10,1)' 
x = 
    90 47 47 44  8 79 45  9 91  6 

>> cumsum(x) 
ans = 
    90 137 184 228 236 315 360 369 460 466 

>> i = max(find(cumsum(x)<=360)) 
i = 
    7 
+0

感謝您的快速回復。 我曾嘗試過,但沒有奏效。它基本上給出了最後一行的數字(在這種情況下是15550),而在第10行的數值是360。所以我應該是第10行 – user3462307

+0

你一定犯了錯誤。上面的代碼應該可以工作。看到我的結果張貼在答案中。 – Kavka

+0

不知道它是什麼,但你是對的,現在第一部分工作。 – user3462307

4

您可以使用以下代碼找到發生事件的行索引。基本上,你要使用模運算符找到其中Turn第一列的總和爲360

mod360 = mod(cumsum(Turn(:,1)),360); 
eventInds = find(mod360 == 0); 

然後,您可以遍歷eventInds放置任何值你在想多在Turn的第二列中有適當的行。

我不認爲你可以在字段中放置字符串'event 1',但是由於字符串數組像行爲一樣會導致維度不匹配。您可以將第一個事件的數值1和第二個事件的2等存儲起來。

+0

所以在mod360矩陣中,我發現它達到360時的實例? 事件的數字編號也很好 – user3462307

+0

巧妙地使用模運算來查找索引。 +1 – Kavka

+0

+1確實使用'mod'! – Divakar

1

瑞恩的答案看起來像要走的路。但是如果你的條件是這樣的,你需要找到累計和不是360的行數,那麼你將需要做更多的工作。對於這種情況,你可以使用這個 -

試試這個矢量(無環路)的代碼來獲得,其中360組出現的行ID -

threshold = 360; 
cumsum_val = cumsum(Turn); 
ind1 = find(cumsum_val>=threshold,1) 
num_events = floor(cumsum_val(end)/threshold); 
[x1,y1] = find(bsxfun(@gt,cumsum_val,threshold.*(1:num_events))); 
[~,b,~] = unique(y1,'first'); 
row_nums = x1(b) 

之後,你可以獲取事件數據,如這 -

event1 = Turn(1:row_nums(1)); 
event2 = Turn(row_nums(1)+1:row_nums(2)); 
event3 = Turn(row_nums(2)+1:row_nums(3)); 
... 
event21 = Turn(row_nums(20)+1:row_nums(21)); 

... 
eventN = Turn(row_nums(N-1)+1:row_nums(N)); 

編輯1個

樣本案例:

我們創建了一個小數據20隨機整數,而不是15000用於原始問題。此外,我們使用30的閾值而不是360來解釋小數據大小。

代碼

Turn = randi(10,[20 1]); 
threshold = 30; 

cumsum_val = cumsum(Turn); 
ind1 = find(cumsum_val>=threshold,1) 
num_events = floor(cumsum_val(end)/threshold); 
[x1,y1] = find(bsxfun(@gt,cumsum_val,threshold.*(1:num_events))); 
[~,b,~] = unique(y1,'first'); 
row_nums = x1(b); 

運行

Turn = 

    7 
    6 
    3 
    4 
    5 
    3 
    9 
    2 
    3 
    2 
    3 
    5 
    4 
    10 
    5 
    2 
    10 
    10 
    5 
    2 


threshold = 

    30 


row_nums = 

    7 
    14 
    18 

運行結果顯示row_nums7, 14, 18,這意味着第二分組與Turn第七屆索引開始,第三組開始在第14指數等等。當然,您可以在row_nums的開頭追加1來表示第一個分組從第一個索引開始。

+0

我試過這種方法,它的工作部分。事件的數量是正確的,但是row_nums給出了8次1 – user3462307

+0

@ user3462307'row_nums'基本上是'Turn'的行索引的向量,其中每個這樣的360個分組開始。在上面的編輯1部分閱讀更多關於它的信息。 – Divakar