[英]splitting list in dataframe columns to separate columns
我的數據框如下所示
col1 col2 col3
0 [1, a] [1, a1] [1, a2]
1 [2, b] [2, b1] [2, b2]
2 [3, c] [3, c1] [3, c2]
我需要讓它看起來像:
col1 col2 col3 col4
0 a a1 a2 1
1 b b1 b2 2
2 c c1 c2 3
我的代碼
import pandas as pd
d = {'col1':[[1,'a'],[2,'b'],[3,'c']],
'col2':[[1,'a1'],[2,'b1'],[3,'c1']],
'col3':[[1,'a2'],[2,'b2'],[3,'c2']]}
df = pd.DataFrame.from_dict(d)
到目前為止,我已經嘗試使用 apply(pd.Series) 並遍歷 for 循環來重新分配值並且沒有成功
這是使用applymap
和map
的方法:
df.applymap(lambda x: x[-1]).assign(col4 = df['col1'].map(lambda x: x[0]))
根據評論(行中所有列的第一個值相同):
print(
df.apply(lambda x: [v[1] for v in x] + [x[0][0]], axis=1)
.apply(pd.Series)
.rename(columns=lambda x: "col{}".format(x + 1))
)
印刷:
col1 col2 col3 col4
0 a a1 a2 1
1 b b1 b2 2
2 c c1 c2 3
或者:
df = pd.concat(
[
df.transform(lambda x: [v[1] for v in x], axis=1),
df.apply(lambda x: x[0][0], axis=1).rename("col4"),
],
axis=1,
)
print(df)
印刷:
col1 col2 col3 col4
0 a a1 a2 1
1 b b1 b2 2
2 c c1 c2 3
您可以使用 pandas 的字符串方法來訪問這些值:
(df.assign(col1 = df.col1.str[-1],
col2 = df.col2.str[-1],
col3 = df.col3.str[-1],
col4 = df.col1.str[0])
)
col1 col2 col3 col4
0 a a1 a2 1
1 b b1 b2 2
2 c c1 c2 3
通過使用字典理解,您可以使其更通用:
result = {col : df[col].str[-1] for col in df}
col4 = df.col1.str[0]
df.assign(**result, col4 = col4)
col1 col2 col3 col4
0 a a1 a2 1
1 b b1 b2 2
2 c c1 c2 3
您可以很好地將其轉儲到 python 並創建一個新的 dataframe:
outcome = {key: [ent[-1] for ent in value]
for key, value in df.items()}
col4 = {'col4' : [value[-0] for value in df.col1]}
outcome = outcome | col4 # python 3.9, for earlier {**outcome, **col4}
pd.DataFrame(outcome)
col1 col2 col3 col4
0 a a1 a2 1
1 b b1 b2 2
2 c c1 c2 3
numpy 解決方案:
import numpy as np
import pandas as pd
df = pd.DataFrame({
'col1': {0: [1, 'a'], 1: [2, 'b'], 2: [3, 'c']},
'col2': {0: [1, 'a1'], 1: [2, 'b1'], 2: [3, 'c1']},
'col3': {0: [1, 'a2'], 1: [2, 'b2'], 2: [3, 'c2']}
})
a = np.array(df.values.tolist())
new_df = pd.DataFrame(
np.concatenate((a[..., 1], a[:, 0, 0, None]), axis=1),
columns=[*df.columns, 'col4']
)
print(new_df)
new_df
:
col1 col2 col3 col4
0 a a1 a2 1
1 b b1 b2 2
2 c c1 c2 3
通過 perfplot 的一些時間信息:
import numpy as np
import pandas as pd
import perfplot
def gen_data(n):
df = pd.DataFrame(
{'col1': [[1, 'a']],
'col2': [[1, 'a1']],
'col3': [[1, 'a2']]},
)
df = df.loc[np.repeat(df.index.values, n)]
return df
def applymap(df):
return df.applymap(lambda x: x[-1]).assign(
col4=df['col1'].map(lambda x: x[0]))
def apply_series(df):
return df.apply(lambda x: [v[1] for v in x] + [x[0][0]], axis=1) \
.apply(pd.Series) \
.rename(columns=lambda x: "col{}".format(x + 1))
def pd_concat(df):
return pd.concat(
[
df.transform(lambda x: [v[1] for v in x], axis=1),
df.apply(lambda x: x[0][0], axis=1).rename("col4"),
],
axis=1,
)
def str_accessors(df):
return df.assign(col1=df.col1.str[-1],
col2=df.col2.str[-1],
col3=df.col3.str[-1],
col4=df.col1.str[0])
def str_accessors_generic(df):
result = {col: df[col].str[-1] for col in df}
col4 = df.col1.str[0]
return df.assign(**result, col4=col4)
def dump_into_python(df):
outcome = {key: [ent[-1] for ent in value]
for key, value in df.items()}
col4 = {'col4': [value[-0] for value in df.col1]}
outcome = outcome | col4
return pd.DataFrame(outcome)
def numpy_sol(df):
a = np.array(df.values.tolist())
return pd.DataFrame(
np.concatenate((a[..., 1], a[:, 0, 0, None]), axis=1),
columns=[*df.columns, 'col4']
)
if __name__ == '__main__':
out = perfplot.bench(
setup=gen_data,
kernels=[
applymap,
apply_series,
pd_concat,
str_accessors,
str_accessors_generic,
dump_into_python,
numpy_sol
],
labels=[
'applymap_map (rhug123)',
'apply_series (Andrej Kesely)',
'pd_concat (Andrej Kesely)',
'str_accessors (sammywemmy)',
'str_accessors_generic (sammywemmy)',
'dump_into_python (sammywemmy)',
'numpy_sol (Henry Ecker)',
],
n_range=[2 ** k for k in range(18)],
equality_check=None
)
out.save('perfplot_results.png', transparent=False)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.