Python 根据列名的一部分对 Dataframe 列进行分类
Python Categorizing Dataframe columns based on part of the colomn name
可重现数据:
import random
data = {'test_1_a':random.sample(range(1, 50), 7),
'test_1_b':random.sample(range(1, 50), 7),
'test_1_c':random.sample(range(1, 50), 7),
'test_2_a':random.sample(range(1, 50), 7),
'test_2_b':random.sample(range(1, 50), 7),
'test_2_c':random.sample(range(1, 50), 7),
'test_3_a':random.sample(range(1, 50), 7),
'test_4_b':random.sample(range(1, 50), 7),
'test_4_c':random.sample(range(1, 50), 7)}
df = pd.DataFrame(data)
描述:
我有一个类似于我上面给出的示例的数据框,其中包含 1000 列左右。列名格式如下:
test_number_family 所以 test_1_c 将是数字类型 1 和“c”的族
我想按相同“系列”类型的列名对 df 进行分类。所以我的最终输出需要是相同系列值列表的列表:
输出示例:
[[a_familily 个值],[b_familily 个值],...]
它也看起来像列的值:
[ [test_1_a, test_2_a , test_3_a ] , [test_1_b, test_2_b , test_3_b ] , ...]
我有:
#### transfers data frame into a sorted dict (by column name) by columns as key
col_names = [ i for (i,j) in df.iteritems() ]
col_vals = [ j for (i,j) in df.iteritems() ]
df_dict = dict(zip(col_names, col_vals))
families = np.unique([ i.split("_")[2] for i in dict1.keys() ])
我已将每个列名称及其关联值分类,并提取了我希望在最终输出中作为“家庭”拥有的唯一组数。我现在正在寻求帮助,将数据框分类为与我上面给出的输出示例相同的长度(系列)数量的列表。
希望我的解释很清楚,感谢您抽出宝贵的时间!
让我们跟踪字典中的不同族,键是字母(族),值是包含某个族的列的列表。
因为我们知道每一列都以与其家族相关的字母结尾,所以我们可以将其用作字典中的键。
from collections import defaultdict
families = defaultdict(list)
for col in df.columns:
families[col[-1]].append(df[col])
现在例如,在families["a"]
中,我们有:
[0 26
1 13
2 11
3 35
4 43
5 45
6 46
Name: test_1_a, dtype: int64,
0 10
1 15
2 20
3 43
4 40
5 35
6 22
Name: test_2_a, dtype: int64,
0 35
1 48
2 38
3 13
4 3
5 10
6 25
Name: test_3_a, dtype: int64]
我们可以使用 concat
.
轻松获得 per-family 数据框
df_a = pd.concat(families["a"], axis=1)
得到我们:
test_1_a test_2_a test_3_a
0 26 10 35
1 13 15 48
2 11 20 38
3 35 43 13
4 43 40 3
5 45 35 10
6 46 22 25
如果我们要为每个家庭创建一个数据框字典,
dfs = {f"df_{fam}" : pd.concat(families[fam], axis=1) for fam in families.keys()}
现在,字典 dfs
包含:
{'df_a': test_1_a test_2_a test_3_a
0 26 10 35
1 13 15 48
2 11 20 38
3 35 43 13
4 43 40 3
5 45 35 10
6 46 22 25,
'df_b': test_1_b test_2_b test_4_b
0 18 4 44
1 48 43 2
2 30 21 4
3 46 12 16
4 42 14 25
5 22 24 13
6 43 40 43,
'df_c': test_1_c test_2_c test_4_c
0 25 15 5
1 36 39 28
2 6 3 37
3 22 48 16
4 2 34 25
5 39 16 30
6 32 36 2}
您如何看待这样的方法?将 pd.wide_to_long
与带有拆分列的长数据帧的结果一起使用,一个包含整个 classification
,如 1_a
,一个仅包含数字,一个包含家庭及其值。
df = (pd.wide_to_long(
df.reset_index(),stubnames='test_',i='index',j='classification',suffix='\d_\w')
.reset_index()
.drop('index',axis=1)
.rename(columns={'test_':'values'}))
df[['number', 'family']] = df['classification'].str.split('_', expand=True)
df = df.reindex(columns=['classification', 'number', 'family', 'values'])
print(df)
classification number family values
0 1_a 1 a 29
1 1_a 1 a 46
2 1_a 1 a 2
3 1_a 1 a 6
4 1_a 1 a 16
.. ... ... ... ...
58 4_c 4 c 30
59 4_c 4 c 23
60 4_c 4 c 26
61 4_c 4 c 40
62 4_c 4 c 39
易于分组或过滤以进行更多分析。
如果你想获得 dicts
或 lists
的特定数据,这里有一些例子:
filter1 = df.loc[df['classification']=='1_a',:]
filter2 = df.loc[df['number']=='2','values']
filter1.to_dict(orient='list')
Output:
{'classification': ['1_a', '1_a', '1_a', '1_a', '1_a', '1_a', '1_a'],
'number': ['1', '1', '1', '1', '1', '1', '1'],
'family': ['a', 'a', 'a', 'a', 'a', 'a', 'a'],
'values': [29, 46, 2, 6, 16, 12, 38]}
filter2.tolist()
Output:
[8, 2, 43, 9, 5, 30, 28, 26, 25, 49, 3, 1, 47, 44, 16, 9, 8, 15, 24, 36, 1]
不确定我是否完全理解问题;这是你的想法吗:
dict(list(df.groupby(df.columns.str[-1], axis = 1)))
{'a': test_1_a test_2_a test_3_a
0 20 36 14
1 4 7 16
2 28 13 28
3 3 40 9
4 38 41 5
5 34 47 18
6 49 25 46,
'b': test_1_b test_2_b test_4_b
0 35 10 44
1 46 14 23
2 26 11 36
3 17 27 4
4 13 16 42
5 20 38 9
6 41 22 18,
'c': test_1_c test_2_c test_4_c
0 22 2 26
1 42 24 3
2 15 16 41
3 7 11 16
4 40 37 47
5 38 7 33
6 39 22 24}
这会根据列名中的最后一个字母对列进行分组。
如果这不是您想要的,请发表评论,也许可以更好地解释一下我误解了您的意图的地方。
可重现数据:
import random
data = {'test_1_a':random.sample(range(1, 50), 7),
'test_1_b':random.sample(range(1, 50), 7),
'test_1_c':random.sample(range(1, 50), 7),
'test_2_a':random.sample(range(1, 50), 7),
'test_2_b':random.sample(range(1, 50), 7),
'test_2_c':random.sample(range(1, 50), 7),
'test_3_a':random.sample(range(1, 50), 7),
'test_4_b':random.sample(range(1, 50), 7),
'test_4_c':random.sample(range(1, 50), 7)}
df = pd.DataFrame(data)
描述:
我有一个类似于我上面给出的示例的数据框,其中包含 1000 列左右。列名格式如下:
test_number_family 所以 test_1_c 将是数字类型 1 和“c”的族
我想按相同“系列”类型的列名对 df 进行分类。所以我的最终输出需要是相同系列值列表的列表:
输出示例:
[[a_familily 个值],[b_familily 个值],...]
它也看起来像列的值:
[ [test_1_a, test_2_a , test_3_a ] , [test_1_b, test_2_b , test_3_b ] , ...]
我有:
#### transfers data frame into a sorted dict (by column name) by columns as key
col_names = [ i for (i,j) in df.iteritems() ]
col_vals = [ j for (i,j) in df.iteritems() ]
df_dict = dict(zip(col_names, col_vals))
families = np.unique([ i.split("_")[2] for i in dict1.keys() ])
我已将每个列名称及其关联值分类,并提取了我希望在最终输出中作为“家庭”拥有的唯一组数。我现在正在寻求帮助,将数据框分类为与我上面给出的输出示例相同的长度(系列)数量的列表。
希望我的解释很清楚,感谢您抽出宝贵的时间!
让我们跟踪字典中的不同族,键是字母(族),值是包含某个族的列的列表。
因为我们知道每一列都以与其家族相关的字母结尾,所以我们可以将其用作字典中的键。
from collections import defaultdict
families = defaultdict(list)
for col in df.columns:
families[col[-1]].append(df[col])
现在例如,在families["a"]
中,我们有:
[0 26
1 13
2 11
3 35
4 43
5 45
6 46
Name: test_1_a, dtype: int64,
0 10
1 15
2 20
3 43
4 40
5 35
6 22
Name: test_2_a, dtype: int64,
0 35
1 48
2 38
3 13
4 3
5 10
6 25
Name: test_3_a, dtype: int64]
我们可以使用 concat
.
df_a = pd.concat(families["a"], axis=1)
得到我们:
test_1_a test_2_a test_3_a
0 26 10 35
1 13 15 48
2 11 20 38
3 35 43 13
4 43 40 3
5 45 35 10
6 46 22 25
如果我们要为每个家庭创建一个数据框字典,
dfs = {f"df_{fam}" : pd.concat(families[fam], axis=1) for fam in families.keys()}
现在,字典 dfs
包含:
{'df_a': test_1_a test_2_a test_3_a
0 26 10 35
1 13 15 48
2 11 20 38
3 35 43 13
4 43 40 3
5 45 35 10
6 46 22 25,
'df_b': test_1_b test_2_b test_4_b
0 18 4 44
1 48 43 2
2 30 21 4
3 46 12 16
4 42 14 25
5 22 24 13
6 43 40 43,
'df_c': test_1_c test_2_c test_4_c
0 25 15 5
1 36 39 28
2 6 3 37
3 22 48 16
4 2 34 25
5 39 16 30
6 32 36 2}
您如何看待这样的方法?将 pd.wide_to_long
与带有拆分列的长数据帧的结果一起使用,一个包含整个 classification
,如 1_a
,一个仅包含数字,一个包含家庭及其值。
df = (pd.wide_to_long(
df.reset_index(),stubnames='test_',i='index',j='classification',suffix='\d_\w')
.reset_index()
.drop('index',axis=1)
.rename(columns={'test_':'values'}))
df[['number', 'family']] = df['classification'].str.split('_', expand=True)
df = df.reindex(columns=['classification', 'number', 'family', 'values'])
print(df)
classification number family values
0 1_a 1 a 29
1 1_a 1 a 46
2 1_a 1 a 2
3 1_a 1 a 6
4 1_a 1 a 16
.. ... ... ... ...
58 4_c 4 c 30
59 4_c 4 c 23
60 4_c 4 c 26
61 4_c 4 c 40
62 4_c 4 c 39
易于分组或过滤以进行更多分析。
如果你想获得 dicts
或 lists
的特定数据,这里有一些例子:
filter1 = df.loc[df['classification']=='1_a',:]
filter2 = df.loc[df['number']=='2','values']
filter1.to_dict(orient='list')
Output:
{'classification': ['1_a', '1_a', '1_a', '1_a', '1_a', '1_a', '1_a'],
'number': ['1', '1', '1', '1', '1', '1', '1'],
'family': ['a', 'a', 'a', 'a', 'a', 'a', 'a'],
'values': [29, 46, 2, 6, 16, 12, 38]}
filter2.tolist()
Output:
[8, 2, 43, 9, 5, 30, 28, 26, 25, 49, 3, 1, 47, 44, 16, 9, 8, 15, 24, 36, 1]
不确定我是否完全理解问题;这是你的想法吗:
dict(list(df.groupby(df.columns.str[-1], axis = 1)))
{'a': test_1_a test_2_a test_3_a
0 20 36 14
1 4 7 16
2 28 13 28
3 3 40 9
4 38 41 5
5 34 47 18
6 49 25 46,
'b': test_1_b test_2_b test_4_b
0 35 10 44
1 46 14 23
2 26 11 36
3 17 27 4
4 13 16 42
5 20 38 9
6 41 22 18,
'c': test_1_c test_2_c test_4_c
0 22 2 26
1 42 24 3
2 15 16 41
3 7 11 16
4 40 37 47
5 38 7 33
6 39 22 24}
这会根据列名中的最后一个字母对列进行分组。
如果这不是您想要的,请发表评论,也许可以更好地解释一下我误解了您的意图的地方。