2017-06-15 76 views
0

我有一個csv文件,我嘗試使用Azure Data Lake Analytics U-SQL進行處理。我對U-SQL相當陌生,所以請耐心等待。原始文件是我設法使用silent:true標誌修復的半結構化文件。現在它更加結構化了,我想用上面單元格中的數據填充空單元格。如何用上述數據填充空白單元格使用U-SQL

我的數據是這樣的: CSV with empty cells

我的問題在於,在第一四列空單元格。

第二行有我想要複製到它下面的空單元格(第3-5行)的數據。來自第7行的數據需要被複制到第8行,第9行的數據被複制到第10-13行,第14行的數據被複制到第15-18行。

這必須在不更改「金額聲明」列中的值的情況下完成。

有沒有人有任何想法如何在U-SQL中實現這一點?

謝謝。

+0

謝謝大家的指導。我不是開發者,因此可能需要一段時間才能搞清楚,但我真誠地感謝所有的幫助。 – Ally

回答

0

我想你可以通過使用U-SQL用戶定義的操作符(UDO)來解決這個問題。在UDO中,您將逐行進行迭代,每當您獲得具有空值的行時,都會複製前一行的數據。

+0

**行集沒有順序** - 它們是邏輯數據容器,類似於非重複哈希集合。序列化行的原始順序不會隱式轉移到行集(從而轉移到UDO),它需要重新創建。請注意,只要您的方法*採用*順序 - 任何行間順序都必須在語言中明確指定。 – Nabeel

+0

**可以創建訂單** - 您可以使用預設來維護單個頂點上的訂單並處理數據,以確保其順序工作。你可以通過這篇文章獲得更多的幫助,如果你不明白它是如何工作的,請告訴我:https://blogs.msdn.microsoft.com/mrys/2016/06/08/how-do-i -combine-overlapping-ranges-using-u-sql -introducing -u-sql-reducer-udos/ – Jamil

+0

我在一年多前遇到過類似的情況,下面是對此的一些討論:https://stackoverflow.com/questions/35624870/azure-data-lake-analytics-combine-overlapping-time-duration-using-u-sql希望它能幫助你學習。 – Jamil

2

U型SQL一般是處理語言順序無關數據 - 這個問題是不是一個好適合它

  • 沒有排排序標準在輸入數據中。
  • 在U-SQL中重新創建輸入行排序只能通過限制提取到1個頂點來完成 - 這限制了輸入數據的大小,並且與使用並行大型數據處理語言有些不一致。

行集 - 基本的USQL構建塊 - 是無序的邏輯數據容器。因此,在您將其讀入行集時,原始輸入中行的順序會丟失;您必須使用某個排序鍵在U-SQL內重新創建訂單。

假設有這樣一個排序鍵,

@data = SELECT A, LAST_VALUE(Col == "" ? null : Col) OVER (ORDER BY Key ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS Col FROM @input; 

應該做到這一點,因爲LAST_VALUE 應該忽略空值。注 - USQL documentation實際上並未指定是否忽略空值 - 它們應該按照常規聚合/窗口函數約定進行,但需要對其進行驗證。

您的數據沒有排序的列 - 創建一個,你需要

  1. 確保所有的數據由1個頂點處理 - [SqlUserDefinedExtractor(AtomicFileProcessing = true)]
  2. 定製提取中添加排序列。

這對於您在上傳之前可以在本地處理的大量數據來說可能過於複雜。

0

另一種方法(LAST_VALUE不爲我工作):

如果你有行號或時間戳字段則沒有問題

@tb1 = SELECT * FROM 
     (VALUES 
     (1, "Noah1"), 
     (2, (string)null), 
      (3, "Noah3"), 
      (5, (string) null), 
      (6, (string)null), 
      (7, "Noah6"), 
      (8, "Noah7") 
     ) AS T(Timestamp, a); 


@tb1 = 
    SELECT Timestamp, 
      [a], 
      [a] != null && [a] != LEAD([a], 1) OVER(ORDER BY Timestamp ASC) AS aSwitch 
    FROM @tb1; 

@tb1 = 
    SELECT Timestamp, 
      [a], 
      SUM(aSwitch ? 1 : 0) OVER(ORDER BY Timestamp ASC ROWS UNBOUNDED PRECEDING) AS aGrp 
    FROM @tb1; 

@tb1 = 
    SELECT Timestamp, 
      FIRST_VALUE([a]) OVER(PARTITION BY aGrp ORDER BY Timestamp ASC) AS aFilled 
    FROM @tb1; 

OUTPUT @tb1 TO "/test.csv" USING Outputters.Csv(outputHeader: true); 

結果:

"Timestamp","aFilled" 
1,"Noah1" 
2,"Noah1" 
3,"Noah3" 
5,"Noah3" 
6,"Noah3" 
7,"Noah6" 
8,"Noah7" 

但是如果你沒有這樣的領域該怎麼辦?在簡單的情況下,你可以使用啞場:

@tb1 = SELECT * FROM 
     (VALUES 
     ("Noah1"), 
     ((string)null), 
      ("Noah3"), 
      ((string) null), 
      ((string)null), 
      ("Noah6"), 
      ("Noah7") 
     ) AS T(a); 

@tb1 = SELECT 1 AS Timestamp, 
       [a] 
      FROM @tb1; 
相關問題