我有以下資料框
id rule1 rule2 rule3
1 True True False
2 True True True
3 False False False
4 False True False
5 True False True
..
和一本字典:
{'rule1': 'Rule one', 'rule2': 'Rule two', 'rule3': 'Rule three'}
我想得到一個額外的列list_of_rules,它是True上面資料框中的字典中的規則串列。
id rule1 rule2 rule3 list_of_rules
1 True True False ['Rule one', 'Rule two']
2 True True True ['Rule one', 'Rule two', 'Rule three']
3 False False False ['']
4 False True False ['Rule two']
5 True False True ['Rule one', 'Rule three']
..
到目前為止,我有以下解決方案:
df.loc[df['rule1'] == True, 'rule1'] = 'Rule one'
df.loc[df['rule2'] == True, 'rule2'] = 'Rule two'
df.loc[df['rule3'] == True, 'rule3'] = 'Rule three'
df.loc[df['rule1'] == False, 'rule1'] = ''
df.loc[df['rule2'] == False, 'rule2'] = ''
df.loc[df['rule3'] == False, 'rule3'] = ''
df['list_of_rules'] = df[['rule1', 'rule2', 'rule3']].apply("-".join, axis=1).str.strip('-').str.split('-')
df
給出以下輸出:
id rule1 rule2 rule3 list_of_rules
1 True True False ['Rule one', 'Rule two']
2 True True True ['Rule one', 'Rule two', 'Rule three']
3 False False False ['']
4 False True False ['Rule two']
5 True False True ['Rule one', , 'Rule three']
..
有沒有辦法修復第五行,所以不會有雙逗號?另外,我想直接使用上面的字典。
先感謝您
uj5u.com熱心網友回復:
鑒于:
df = pd.DataFrame({'id': {0: 1, 1: 2, 2: 3, 3: 4, 4: 5}, 'rule1': {0: True, 1: True, 2: False, 3: False, 4: True}, 'rule2': {0: True, 1: True, 2: False, 3: True, 4: False}, 'rule3': {0: False, 1: True, 2: False, 3: False, 4: True}})
df.set_index("id", inplace=True)
d = {'rule1': 'Rule one', 'rule2': 'Rule two', 'rule3': 'Rule three'}
你可以使用這個:
df.apply(lambda row: [d[rule] for rule in df.columns if row[rule]], axis=1)
或者可以使用 True 評估為 1 而 False 評估為 0 的事實。
df.mul(d).apply(lambda row: list(filter(None, row)), axis=1)
兩者都為您提供所需的輸出,而無需處理連接、剝離和拆分。
uj5u.com熱心網友回復:
嘗試使用以下小技巧pandas.Dataframe.dot:
import pandas as pd
data_dict = {'id': {0: 1, 1: 2, 2: 3, 3: 4, 4: 5},
'rule1': {0: True, 1: True, 2: False, 3: False, 4: True},
'rule2': {0: True, 1: True, 2: False, 3: True, 4: False},
'rule3': {0: False, 1: True, 2: False, 3: False, 4: True}}
df = pd.DataFrame(data_dict)
df = df.set_index('id')
d = {'rule1': 'Rule one', 'rule2': 'Rule two', 'rule3': 'Rule three'}
dfr = df.rename(columns=d)
df['list_of_rules'] = dfr.dot(dfr.columns '-').str.strip('-').str.split('-')
df.reset_index()
輸出:
id rule1 rule2 rule3 list_of_rules
0 1 True True False [Rule one, Rule two]
1 2 True True True [Rule one, Rule two, Rule three]
2 3 False False False []
3 4 False True False [Rule two]
4 5 True False True [Rule one, Rule three]
讓我們檢查時間對資料幀大小的影響:
from timeit import timeit
def bitflip_apply(df):
d = {'rule1': 'Rule one', 'rule2': 'Rule two', 'rule3': 'Rule three'}
return df.apply(lambda row: [d[rule] for rule in df.columns if row[rule]], axis=1)
def bitflip_mul(df):
d = {'rule1': 'Rule one', 'rule2': 'Rule two', 'rule3': 'Rule three'}
return df.mul(d).apply(lambda row: list(filter(None, row)), axis=1)
def scottb_dot(df):
d = {'rule1': 'Rule one', 'rule2': 'Rule two', 'rule3': 'Rule three'}
dfr = df.rename(columns=d)
return dfr.dot(dfr.columns '-').str.strip('-').str.split('-')
res = pd.DataFrame(
index=[1, 10, 30, 100, 300, 1000],
columns='bitflip_apply bitflip_mul scottb_dot'.split(),
dtype=float
)
for i in res.index:
data_dict = {'id': {0: 1, 1: 2, 2: 3, 3: 4, 4: 5},
'rule1': {0: True, 1: True, 2: False, 3: False, 4: True},
'rule2': {0: True, 1: True, 2: False, 3: True, 4: False},
'rule3': {0: False, 1: True, 2: False, 3: False, 4: True}}
df = pd.DataFrame(data_dict)
df = df.set_index('id')
d = pd.concat([df]*i)
for j in res.columns:
stmt = '{}(d)'.format(j)
setp = 'from __main__ import d, {}'.format(j)
res.at[i, j] = timeit(stmt, setp, number=100)
res.plot(loglog=True)
輸出:

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/518398.html
上一篇:在串列串列中查找重復項
下一篇:串列理解以獲得第二個和第四個元素
