簡體   English   中英

用 C++ 構建數據框

[英]Building a dataframe in C++

我正在嘗試用 C++ 構建一個 DataFrame。 我面臨一些問題,例如處理可變數據類型。

我正在考慮受 Pandas DataFrame(來自 python)啟發的 DataFrame。 所以我的設計思路是:

  1. 構建一個對象“系列”,它是一個固定數據類型的向量。
  2. 構建一個對象“DataFrame”,它將存儲一個系列列表(該列表可以是可變的)。

項目 1. 只是一個常規向量。 因此,例如,用戶會調用

Series.fill({1,2,3,4}) 並將向量 {1,2,3,4} 存儲在 Series 的某個屬性中,比如 Series.data。

問題 1. 我如何制作一個將 {1,2,3,4} 理解為 4 個整數向量的類。 是否可以?

下一個問題是:

關於 2.,我可以將 DataFrame 視為 n 列 m 行的矩陣,但列可以具有不同的數據類型。

我試圖將其設計為一個包含 n 個指針的向量,其中每個指針將指向一個具有不同數據類型的 m 維向量。

我試着做類似的事情

vector<void*> columns(10)

並用類似的東西填充它

columns[0] = (int*) malloc(8*sizeof(int))

但這不起作用,如果我嘗試填充向量,例如

(*columns[0])[0] = 5;

我收到一個錯誤

::value_type {aka void*}' is not a pointer-to-object type (int *) (*a[0])[0] = 5;

我怎樣才能正確地做到這一點? 我還有其他問題,例如,如何將未確定數量的 Series 附加到 DataFrame 中,但就目前而言,僅構建具有不同數據類型的列的矩陣是一個很好的開始。

我知道我必須跟蹤我的 void 向量中的指針類型,但我可以創建一個包含所有數據類型的並行列表,並將其作為我的類 DataFrame 的一個屬性。

TL;DR 版本

放棄你正在做的事情。

使用vector<vector<int>> columns; . 當您需要一列時,請使用columns[index].data()index ed 內部vector獲取指向后備數組的指針,並將該int *傳遞給需要的任何void * int *將被隱式轉換。

解釋

引用 cppreference

void - 帶有空值集的類型。 它是無法完成的不完整類型(因此,不允許使用 void 類型的對象)。 沒有 void數組,也沒有對 void 的引用 但是,允許指向 void和返回類型 void 的函數(其他語言中的過程)。

因為 void 是不完整的,所以你不能有一個void void*需要轉換回實際數據類型int* ,然后才能將其用於傳遞匿名類型指針以外的任何內容。 void *所有接收者都必須知道除了傳遞它之外,對它做任何事情的真正含義。

需要void *參數的函數將接受您提供給它們的任何指針,而無需您做任何進一步的努力,因此幾乎不需要在 C++ 中創建void *變量。 幾乎所有需要void *都用多態或模板填充。 上次我在 C++ 中使用void *是在我將 C++ 編寫為 C 並附加了類時回來的。

錯誤

給定的

vector<void*> columns(10);

其中每個元素將包含一個int數組,讓我們解決

(*columns[0])[0] = 5;

一步一步地看看我們有什么類型,並確保每一步的類型是一致的

columns[0]

獲取vector中的第一個元素,一個void* 到現在為止還挺好。

*columns[0]

取消引用columns[0]處的void* 正如序言中所述,這是無法做到的。 你不能取消引用void *因為你有一個void類型的值這會產生報告的::value_type {aka void }' is not a pointer-to-object type* 錯誤消息。

我們可以

*reinterpret_cast<int*>(columns[0])

把它變成一個指向int的指針,我們可以取消引用並匹配初始類型,並接收一個int ,特別是數組中的第一個 int 。

(*reinterpret_cast<int*>(columns[0]))[0]

會失敗,因為你不能索引一個int 那就像寫42[0] 這意味着取消引用是不必要的。

最終結果需要看起來像

reinterpret_cast<int*>(columns[0])[0]

但不要這樣做。 這是不必要的,而且過於復雜。

在 C++ 中構建異構容器(數據幀應該是)比您想象的要復雜,因為 C++ 是靜態類型的。 這意味着您必須在編譯時知道所有類型。 您的方法使用指針向量(這種方法有一些變體,我不會介紹)。 這種方法非常低效,因為指針指向整個內存並破壞您的緩存位置。 我什至不建議嘗試實現這樣的數據框,因為它真的沒有意義。

看看這個用 C++ 實現的 DataFrame: https : //github.com/hosseinmoein/DataFrame 您也許可以按原樣使用它。 或者從中了解如何實現真正的異構 DataFrame。 它使用哈希表中的一組靜態向量來實現真正的異構容器。 它還使用連續的內存空間,因此避免了指針效應。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM