我有資料框,例如。像下面
Event['EVENT_ID'] = [ 4162, 4161, 4160, 4159,4158, 4157, 4156, 4155, 4154]
需要將每一行字轉換為二進制。
Event['b']=bin(Event['EVENT_ID']) doesn't work
TypeError: cannot convert the series to <class 'int'>
預期帶有二進制的新列,洗掉 0b 并將列拆分為 16 個單獨的列
bin(4162) = '0b1000001000010'
uj5u.com熱心網友回復:
編輯:雖然我在正確的軌道上,但這個實作實際上比其他答案慢得多。請參閱@ZaeroDivide 的回答。
我不認為使用bin函式和使用str型別特別有效。請考慮使用位掩碼。
for i in range(16):
df[f"bit{i}"] = df["EVENT_ID"].apply(lambda x: x & 1 << i).astype(bool).astype(int)
用你的資料測驗,我有以下結果
EVENT_ID B bit0 bit1 bit2 bit3 bit4 bit5 bit6 bit7 \
0 4162 1000001000010 0 1 0 0 0 0 1 0
1 4161 1000001000001 1 0 0 0 0 0 1 0
2 4160 1000001000000 0 0 0 0 0 0 1 0
3 4159 1000000111111 1 1 1 1 1 1 0 0
4 4158 1000000111110 0 1 1 1 1 1 0 0
5 4157 1000000111101 1 0 1 1 1 1 0 0
6 4156 1000000111100 0 0 1 1 1 1 0 0
7 4155 1000000111011 1 1 0 1 1 1 0 0
8 4154 1000000111010 0 1 0 1 1 1 0 0
bit8 bit9 bit10 bit11 bit12 bit13 bit14 bit15
0 0 0 0 0 1 0 0 0
1 0 0 0 0 1 0 0 0
2 0 0 0 0 1 0 0 0
3 0 0 0 0 1 0 0 0
4 0 0 0 0 1 0 0 0
5 0 0 0 0 1 0 0 0
6 0 0 0 0 1 0 0 0
7 0 0 0 0 1 0 0 0
8 0 0 0 0 1 0 0 0
uj5u.com熱心網友回復:
你也可以使用 numpy,比 pandas 快得多。
view編輯:在這里使用幾個技巧更快的 numpy :
- 僅使用感興趣的列
- 將底層陣列轉換為
uint16, 以確保與任何整數輸入兼容 - 交換位元組以獲得正確的 H、L 順序(至少在我的架構上)
- 在不實際移動任何資料的情況下拆分 H,L
view - 相應地運行
unpackbits和重塑
我的機器需要byteswap將 uint16 的位元組放在適當的位置。請注意,這種方法需要將資料作為int16/ uint16,而另一種方法也適用于 int64。
import pandas as pd
import numpy as np
df = pd.DataFrame({'EVENT_ID': [ 4162, 4161, 4160, 4159,4158, 4157, 4156, 4155, 4154]}, dtype='uint16')
zz=np.unpackbits(df.EVENT_ID.values.astype('uint16').byteswap().view('uint8')).reshape(-1,16)
df3 = pd.concat([df,pd.DataFrame(zz)],axis=1)
print(f"{df3 =}")
df3 = EVENT_ID 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 4162 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0
1 4161 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1
2 4160 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0
3 4159 0 0 0 1 0 0 0 0 0 0 1 1 1 1 1 1
4 4158 0 0 0 1 0 0 0 0 0 0 1 1 1 1 1 0
5 4157 0 0 0 1 0 0 0 0 0 0 1 1 1 1 0 1
6 4156 0 0 0 1 0 0 0 0 0 0 1 1 1 1 0 0
7 4155 0 0 0 1 0 0 0 0 0 0 1 1 1 0 1 1
8 4154 0 0 0 1 0 0 0 0 0 0 1 1 1 0 1 0
較舊的建議方法:
lh = np.unpackbits((df.values & 0xFF).astype('uint8')).reshape(-1,8)
uh = np.unpackbits((df.values >> 8).astype('uint8')).reshape(-1,8)
df2 = pd.concat([df, pd.DataFrame(np.concatenate([uh,lh],axis=1),index=df.index)],axis=1)
基準測驗:numpy 比 pandas 快幾個數量級“對于 1M 點:
- numpy 視圖:100 萬
uint64個點需要 35 毫秒 - numpy 低/高:50ms
- pandas list bin:1.78s
- 熊貓應用格式 串列:1.97s
- pandas 應用 lambda:6.08s
df = pd.DataFrame({'EVENT_ID': (np.random.random(int(1e6))*65000).astype('uint16')})
pandas 應用格式串列
In [13]: %timeit df2 = df.join(pd.DataFrame(df['EVENT_ID'].apply('{0:b}'.format).apply(list).tolist()))
1.97 s ± 42.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
熊貓串列箱
In [10]: %%timeit
...: binary_values = pd.DataFrame([list(bin(x)[2:]) for x in df['EVENT_ID']])
...: df2 = df.join(binary_values)
...:
...:
1.78 s ± 53.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
pandas3 應用 lambda
In [5]: %%timeit
...: for i in range(16):
...: df[f"bit{i}"] = df["EVENT_ID"].apply(lambda x: x & 1 << i).astype(bool).astype(int)
...:
6.08 s ± 65.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
麻木的
In [14]: %%timeit
...: lh = np.unpackbits((df.values & 0xFF).astype('uint8')).reshape(-1,8)
...: uh = np.unpackbits((df.values >> 8).astype('uint8')).reshape(-1,8)
...: df3=pd.concat([df, pd.DataFrame(np.concatenate([uh,lh],axis=1),index=df.index)],axis=1)
...:
...:
49.9 ms ± 232 μs per loop (mean ± std. dev. of 7 runs, 10 loops each)
uj5u.com熱心網友回復:
您可以嘗試通過應用將 int 系列轉換為二進制'{0:b}'.format,然后將串列列拆分為多個列pd.DataFrame
df = df.join(pd.DataFrame(df['EVENT_ID'].apply('{0:b}'.format).apply(list).tolist()))
print(df)
EVENT_ID 0 1 2 3 4 5 6 7 8 9 10 11 12
0 4162 1 0 0 0 0 0 1 0 0 0 0 1 0
1 4161 1 0 0 0 0 0 1 0 0 0 0 0 1
2 4160 1 0 0 0 0 0 1 0 0 0 0 0 0
3 4159 1 0 0 0 0 0 0 1 1 1 1 1 1
4 4158 1 0 0 0 0 0 0 1 1 1 1 1 0
5 4157 1 0 0 0 0 0 0 1 1 1 1 0 1
6 4156 1 0 0 0 0 0 0 1 1 1 1 0 0
7 4155 1 0 0 0 0 0 0 1 1 1 0 1 1
8 4154 1 0 0 0 0 0 0 1 1 1 0 1 0
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/479726.html
下一篇:如何過濾熊貓中的串列值
