JSON 是一種廣泛采用的基于文本的信息格式,可在系統(tǒng)之間互操作,最常見于 web 應(yīng)用程序。雖然 JSON 格式是人類可讀的,但使用數(shù)據(jù)科學(xué)和數(shù)據(jù)工程工具處理它很復(fù)雜。
為了彌補(bǔ)這一差距, RAPIDS cuDF 提供了一個 GPU 加速的 JSON 讀取器( cudf.read_json ),該讀取器對于許多 JSON 數(shù)據(jù)結(jié)構(gòu)都是高效和健壯的。 JSON format 指定了一種通用的樹狀數(shù)據(jù)結(jié)構(gòu), cuDF 實現(xiàn)了算法,可以輕松地將 JSON 樹轉(zhuǎn)換為柱狀數(shù)據(jù)。
cuDF 是一個 GPU DataFrame 庫,用于在 Python 中加載、連接、聚合、過濾和以其他方式操作數(shù)據(jù)。當(dāng) JSON 數(shù)據(jù)被構(gòu)造為柱狀數(shù)據(jù)時,它可以訪問強(qiáng)大的 cuDF DataFrame API 。我們很高興能夠通過本讀者打開 GPU 加速到更多數(shù)據(jù)格式、項目和建模工作流的可能性。
本文重點(diǎn)介紹了支持的 JSON 數(shù)據(jù)選項:面向記錄的 JSON 和 JSON 行。以下是幾個 cuDF 讀取器選項的示例,用于處理具有字節(jié)范圍或多個源的 JSON 行文件。最后,您將學(xué)習(xí)如何使用 cuDF 中的工具來展平 cuDF 中的列表和結(jié)構(gòu)類型,以及如何應(yīng)用這些工具從常見的 JSON 模式組裝 DataFrame 。
在 cuDF 中讀取 JSON 數(shù)據(jù)
默認(rèn)情況下, cuDF JSON 讀取器需要使用 records 方向的輸入數(shù)據(jù)。面向記錄的 JSON 數(shù)據(jù)由根級別的對象數(shù)組組成,數(shù)組中的每個對象對應(yīng)一行。對象中的字段名決定表的列名。
JSON 數(shù)據(jù)的另一個常見變體是 JSON 行,其中 JSON 對象由換行符(n)分隔,每個對象對應(yīng)一行。
以下代碼示例顯示了面向記錄的 JSON 以及 JSON 行數(shù)據(jù):
>>> j = '''[ ... {"a": "v1", "b": 12}, ... {"a": "v2", "b": 7}, ... {"a": "v3", "b": 5} ... ]''' >>> df_records = cudf.read_json(j) >>> j = 'n'.join([ ... '{"a": "v1", "b": 12}', ... '{"a": "v2", "b": 7}', ... '{"a": "v3", "b": 5}' ... ]) >>> df_lines = cudf.read_json(j, lines=True) >>> df_lines a b 0 v1 12 1 v2 7 2 v3 5 >>> df_records.equals(df_lines) True
cuDF JSON 讀取器還與嵌套的 JSON 對象和數(shù)組兼容,這些對象和數(shù)組大致映射到結(jié)構(gòu)和列表 data types in cuDF 。
以下示例演示了用于生成列表和結(jié)構(gòu)列以及數(shù)據(jù)類型為列表和結(jié)構(gòu)的任意組合的列的輸入和輸出。
# example with columns types: # list and struct >>> j = '''[ ... {"list": [0, 1, 2], "struct": {"k": "v1"}}, ... {"list": [3, 4, 5], "struct": {"k": "v2"}} ... ]''' >>> df = cudf.read_json(j) >>> df list struct 0 [0, 1, 2] {'k': 'v1'} 1 [3, 4, 5] {'k': 'v2'} # example with columns types: # list> and struct, m:int> >>> j = 'n'.join([ ... '{"a": [{"k": 0}], "b": {"k": [0, 1], "m": 5}}', ... '{"a": [{"k": 1}, {"k": 2}], "b": {"k": [2, 3], "m": 6}}', ... ]) >>> df = cudf.read_json(j, lines=True) >>> df a b 0 [{'k': 0}] {'k': [0, 1], 'm': 5} 1 [{'k': 1}, {'k': 2}] {'k': [2, 3], 'm': 6}
處理大小 JSON 行文件
對于基于 JSON Lines 數(shù)據(jù)的工作負(fù)載, cuDF 包括幫助數(shù)據(jù)處理的讀取器選項:大文件的字節(jié)范圍支持和小文件的多源支持。
字節(jié)范圍支持
一些工作流,如欺詐檢測和用戶行為建模,需要處理可能超過 GPU 內(nèi)存容量的大型 JSON Line 文件。
cuDF 中的 JSON 讀取器支持字節(jié)范圍參數(shù),該參數(shù)指定起始字節(jié)偏移量和字節(jié)大小。讀取器解析在字節(jié)范圍內(nèi)開始的每個記錄,因此,字節(jié)范圍不必與記錄邊界對齊。
在分布式工作流中,字節(jié)范圍使每個工作人員能夠處理數(shù)據(jù)的子集。在過濾和聚合中,字節(jié)范圍允許單個工作人員以塊的形式處理數(shù)據(jù)。
為了避免跳過行或讀取重復(fù)的行,字節(jié)范圍應(yīng)該相鄰,如下例所示。
>>> num_rows = 10 >>> j = 'n'.join([ ... '{"id":%s, "distance": %s, "unit": "m/s"}' % x ... for x in zip(range(num_rows), cupy.random.rand(num_rows)) ... ]) >>> chunk_count = 4 >>> chunk_size = len(j) // chunk_count + 1 >>> data = [] >>> for x in range(chunk_count): ... d = cudf.read_json( ... j, ... lines=True, ... byte_range=(chunk_size * x, chunk_size) ... ) ... data.append(d) >>> df = cudf.concat(data)
多源支持
相比之下,一些工作流需要處理許多小的 JSON 行文件。
cuDF 中的 JSON 讀取器接受數(shù)據(jù)源列表,而不是循環(huán)通過源并連接生成的 DataFrame 。然后將原始輸入作為單個源進(jìn)行有效處理。
cuDF 中的 JSON 讀取器接受源作為文件路徑、原始字符串或類似文件的對象,以及這些源的列表。
>>> j1 = '{"id":0}n{"id":1}n' >>> j2 = '{"id":2}n{"id":3}n' >>> df = cudf.read_json([j1, j2], lines=True)
解包列表和結(jié)構(gòu)數(shù)據(jù)
將 JSON 數(shù)據(jù)讀入帶有列表和結(jié)構(gòu)列類型的 cuDF DataFrame 后,許多工作流的下一步是將數(shù)據(jù)提取或展平為簡單類型。
對于結(jié)構(gòu)列,一種解決方案是使用struct.explode訪問器提取數(shù)據(jù),并將結(jié)果連接到父 DataFrame 。
下面的代碼示例演示如何從結(jié)構(gòu)列中提取數(shù)據(jù)。
>>> j = 'n'.join([ ... '{"x": "Tokyo", "y": {"country": "Japan", "iso2": "JP"}}', ... '{"x": "Jakarta", "y": {"country": "Indonesia", "iso2": "ID"}}', ... '{"x": "Shanghai", "y": {"country": "China", "iso2": "CN"}}' ... ]) >>> df = cudf.read_json(j, lines=True) >>> df = df.drop(columns='y').join(df['y'].struct.explode()) >>> df x country iso2 0 Tokyo Japan JP 1 Jakarta Indonesia ID 2 Shanghai China CN
對于元素順序有意義的列表列,list.get訪問器從特定位置提取元素。然后,可以將生成的cudf.Series對象分配給 DataFrame 中的新列。
下面的代碼示例演示如何從列表列中提取第一個和第二個元素。
>>> j = 'n'.join([ ... '{"name": "Peabody, MA", "coord": [42.53, -70.98]}', ... '{"name": "Northampton, MA", "coord": [42.32, -72.66]}', ... '{"name": "New Bedford, MA", "coord": [41.63, -70.93]}' ... ]) >>> df = cudf.read_json(j, lines=True) >>> df['latitude'] = df['coord'].list.get(0) >>> df['longitude'] = df['coord'].list.get(1) >>> df = df.drop(columns='coord') >>> df name latitude longitude 0 Peabody, MA 42.53 -70.98 1 Northampton, MA 42.32 -72.66 2 New Bedford, MA 41.63 -70.93
最后,對于長度可變的列表列,explode方法將創(chuàng)建一個新的 DataFrame ,每個列表元素作為一行。將分解的 DataFrame 連接到父 DataFrame 上會產(chǎn)生一個具有所有簡單類型的輸出。
以下示例展平列表列,并將其連接到父 DataFrame 中的索引和其他數(shù)據(jù)。
>>> j = 'n'.join([ ... '{"product": "socks", "ratings": [2, 3, 4]}', ... '{"product": "shoes", "ratings": [5, 4, 5, 3]}', ... '{"product": "shirts", "ratings": [3, 4]}' ... ]) >>> df = cudf.read_json(j, lines=True) >>> df = df.drop(columns='ratings').join(df['ratings'].explode()) >>> df product ratings 0 socks 2 0 socks 4 0 socks 3 1 shoes 5 1 shoes 5 1 shoes 4 1 shoes 3 2 shirts 3 2 shirts 4
使用 cuDF 構(gòu)建 JSON 數(shù)據(jù)解決方案
有時,工作流必須使用對象根處理 JSON 數(shù)據(jù)。 cuDF 提供了為此類數(shù)據(jù)構(gòu)建解決方案的工具。要使用對象根處理 JSON 數(shù)據(jù),我們建議將數(shù)據(jù)作為單個 JSON 行讀取,然后拆包生成的 DataFrame 。
以下示例將 JSON 對象作為單行讀取,然后將“ results ”字段提取到新的 DataFrame 中。
>>> j = '''{ ... "metadata" : {"vehicle":"car"}, ... "results": [ ... {"id": 0, "distance": 1.2}, ... {"id": 1, "distance": 2.4}, ... {"id": 2, "distance": 1.7} ... ] ... }''' # first read the JSON object with lines=True >>> df = cudf.read_json(j, lines=True) >>> df metadata records 0 {'vehicle': 'car'} [{'id': 0, 'distance': 1.2}, {'id': 1, 'distan... # then explode the 'records' column >>> df = df['records'].explode().struct.explode() >>> df id distance 0 0 1.2 1 1 2.4 2 2 1.7
關(guān)鍵要點(diǎn)
cuDF JSON 讀取器旨在加速廣泛的 JSON 數(shù)據(jù)工作負(fù)載,包括跨大文件和小文件的簡單和復(fù)雜類型。
這篇文章演示了 cuDF JSON 讀取器與面向記錄和 JSON 行數(shù)據(jù)的常見用法,以及展示字節(jié)范圍和多源支持?,F(xiàn)在,您可以加快處理 JSON 數(shù)據(jù)的方式,并將 JSON 數(shù)據(jù)有效地結(jié)合到工作流中。
-
NVIDIA
+關(guān)注
關(guān)注
14文章
4990瀏覽量
103118 -
gpu
+關(guān)注
關(guān)注
28文章
4742瀏覽量
128972 -
AI
+關(guān)注
關(guān)注
87文章
30947瀏覽量
269213
發(fā)布評論請先 登錄
相關(guān)推薦
評論