簡體   English   中英

如何將一組列標題與其在Pandas中的值進行交換

[英]How to swap a group of column headings with their values in Pandas

我有以下數據框:

a1  | a2  | a3  | a4 
--------------------- 
Bob | Cat | Dov | Edd 
Cat | Dov | Bob | Edd
Edd | Cat | Dov | Bob

我想把它轉換成

Bob | Cat | Dov | Edd
---------------------
a1  | a2  | a3  | a4
a3  | a1  | a2  | a4
a4  | a2  | a3  | a1

請注意,列數等於唯一值的數量,並保留行的數量和順序

1) 所需方法:

更快的實現是對數據幀的值進行排序,並根據在np.argsort之后獲得的索引來相應地對齊列。

pd.DataFrame(df.columns[np.argsort(df.values)], df.index, np.unique(df.values))

在此輸入圖像描述

應用np.argsort為我們提供了我們正在尋找的數據:

df.columns[np.argsort(df.values)]
Out[156]:
Index([['a1', 'a2', 'a3', 'a4'], ['a3', 'a1', 'a2', 'a4'],
       ['a4', 'a2', 'a3', 'a1']],
      dtype='object')

2) 緩慢的廣義方法:

以一些速度/效率為代價的更通用的方法是在創建數據幀中存在的字符串/值的dict映射及其對應的列名之后使用apply

稍后在將獲得的系列轉換為其list表示后使用數據框構造函數。

pd.DataFrame(df.apply(lambda s: dict(zip(pd.Series(s), pd.Series(s).index)), 1).tolist()) 

3) 更快的通用方法:

在從df.to_dict + orient='records'獲得字典列表之后,我們需要交換它各自的鍵和值對,同時在循環中迭代它們。

pd.DataFrame([{val:key for key, val in d.items()} for d in df.to_dict('r')])

示例測試用例:

df = df.assign(a5=['Foo', 'Bar', 'Baz'])

這兩種方法都產生:

在此輸入圖像描述


@piRSquared編輯 1

廣義解

def nic(df):
    v = df.values
    n, m = v.shape
    u, inv = np.unique(v, return_inverse=1)
    i = df.index.values
    c = df.columns.values
    r = np.empty((n, len(u)), dtype=c.dtype)
    r[i.repeat(m), inv] = np.tile(c, n)
    return pd.DataFrame(r, i, u)

1 我要感謝用戶@ piRSquared提出了一個非常快速和通用的基於numpy的替代解決方案。

您可以使用堆棧重新整形並使用交換值和索引取消堆棧:

df_swap = (df.stack()                     # reshape the data frame to long format
             .reset_index(level = 1)      # set the index(column headers) as a new column
             .set_index(0, append=True)   # set the values as index
             .unstack(level=1))           # reshape the data frame to wide format

df_swap.columns = df_swap.columns.get_level_values(1)   # drop level 0 in the column index
df_swap

在此輸入圖像描述

numpy + pandas

v = df.values
n, m = v.shape
i = df.index.values
c = df.columns.values

# create series with values that were column values
# create multi index with first level from existing index
# and second level from flattened existing values
# then unstack
pd.Series(
    np.tile(c, n),
    [i.repeat(m), v.ravel()]
).unstack()

  Bob Cat Dov Edd
0  a1  a2  a3  a4
1  a3  a1  a2  a4
2  a4  a2  a3  a1

暫無
暫無

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

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