匹配数据集中的列与其 class,类似于 VLOOKUP
Matching columns in data set with its class, similar to VLOOKUP
我有一个大数据集,它的头部如下所示:
Time Company 1 Company 2 ... Company 12 Company 13 Company 14
0 1/01/2015 49 19 ... 80 56 61
1 2/01/2015 2 92 ... 28 98 72
2 3/01/2015 39 69 ... 93 10 66
3 4/01/2015 31 54 ... 78 9 84
4 5/01/2015 37 81 ... 59 32 99
5 6/01/2015 83 69 ... 67 12 69
6 7/01/2015 38 7 ... 37 50 22
7 8/01/2015 75 90 ... 29 99 90
8 9/01/2015 2 7 ... 4 84 59
9 10/01/2015 14 66 ... 40 51 78
10 11/01/2015 20 87 ... 7 26 52
11 12/01/2015 33 84 ... 80 81 69
12 13/01/2015 93 90 ... 4 55 65
13 14/01/2015 95 47 ... 16 43 75
14 15/01/2015 71 66 ... 53 36 0
15 16/01/2015 98 26 ... 41 48 31
16 17/01/2015 29 29 ... 3 13 9
17 18/01/2015 46 96 ... 99 52 71
18 19/01/2015 27 91 ... 50 65 21
19 20/01/2015 45 64 ... 24 97 87
[20 rows x 15 columns]
这是一个 csv 文件,然后我有一个单独的 csv 文件,上面写着哪个 company
在哪个 class
中,像这样:
Company1 B
0 Company2 B
1 Company3 C
2 Company4 A
3 Company5 A
4 Company6 A
5 Company7 C
6 Company8 B
7 Company9 A
8 Company10 A
9 Company11 B
10 Company12 C
11 Company13 A
12 Company14 C
我想去掉 company1,...,company14
列,只保留 A,B,C
列。我知道如何在 excel 中使用一个简单的 VLOOKUP
函数来做到这一点,但是我的数据集非常大,因此在 excel 中使用 VLOOKUP
是不可行的。
有什么方法可以使用 python 达到我想要的结果吗?
这是我想要的输出:
Time A B C
0 1/01/2015 283 228 230
1 2/01/2015 303 158 224
2 3/01/2015 243 163 277
3 4/01/2015 306 259 250
4 5/01/2015 257 232 242
5 6/01/2015 258 160 288
6 7/01/2015 406 136 170
7 8/01/2015 407 180 239
8 9/01/2015 283 98 127
9 10/01/2015 321 144 248
10 11/01/2015 344 296 212
11 12/01/2015 372 175 243
12 13/01/2015 133 249 181
13 14/01/2015 251 245 214
14 15/01/2015 227 263 226
15 16/01/2015 344 154 180
16 17/01/2015 361 146 124
17 18/01/2015 337 290 245
18 19/01/2015 252 247 212
19 20/01/2015 315 169 219
编辑 1:
Company1 B
0 Company2 B
1 Company3 C
2 Company4 A
3 Company5 A
4 Company6 A
5 Company7 C
6 Company8 B
7 Company9 A
8 Company10 A
9 Company11 B
10 Company12 C
11 Company13 A
12 Company14 C
13 Company15 B
14 Company16 B
15 Company17 C
16 Company18 A
17 Company19 A
18 Company20 A
19 Company21 C
20 Company22 B
21 Company23 A
22 Company24 A
23 Company25 B
24 Company26 C
25 Company27 A
26 Company28 C
27 Company29 B
28 Company30 B
29 Company31 C
.. ... ..
301 Company303 A
302 Company304 A
303 Company305 B
304 Company306 C
305 Company307 A
306 Company308 C
307 Company309 B
308 Company310 B
309 Company311 C
310 Company312 A
311 Company313 A
312 Company314 A
313 Company315 C
314 Company316 B
315 Company317 A
316 Company318 A
317 Company319 B
318 Company320 C
319 Company321 A
320 Company322 C
321 Company323 B
322 Company324 B
323 Company325 C
324 Company326 A
325 Company327 A
326 Company328 A
327 Company329 C
328 Company330 B
329 Company331 A
330 Company332 A
[331 rows x 2 columns]
您需要执行四个不同的操作才能达到您想要的状态。看起来您正在使用 pandas,所以我将概述一个使用 pandas 的解决方案。
- 融化 大数据框。这使您能够以类似于在 excel 中使用数据透视表 table 的方式将列转换为行。
- 合并 大数据框(左边)和小数据框(右边)。这是一个更强大的 vlookup 版本。您想要在 time 和 class 上使用 left join。
- 聚合 合并的结果并按时间 分组。我假设您想求和,但您可以执行许多其他聚合函数,例如计数、最小值、最大值。查看 pandas 文档了解更多详情。
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.sum.html
- 将数据旋转 到您想要的结果形状。枢轴与 melt 相反。随着融化,我们将列转换为行。使用枢轴,我们将行变成列,
这是按逻辑步骤编写的代码片段,并非为了获得最佳性能。希望您可以逐步完成每个步骤以便更好地理解。请注意,我将 headers 放在 csv 文件中,因此您可能需要根据导入数据的方式在数据框中声明列名。
largeCsv Headers: 时间,Company1,Company2,Company3,Company4,Company5[=16=]
smallCsv Headers: 姓名, class
import pandas as pd
dfSmall = pd.read_csv('c:/temp/smallCsv.csv')
dfLarge = pd.read_csv('c:/temp/largeCsv.csv')
dfMeltedLarge = pd.melt(dfLarge, id_vars=['Time'], var_name='name')
dfMerged = dfMeltedLarge.merge(dfSmall, on='name', how='left')[['Time', 'class', 'value']]
dfSum = dfMerged.groupby(['Time', 'class']).sum()
dfResult = dfSum.pivot_table(index='Time', columns='class', values='value')
下面是您可以 运行 代码使用的可重现数据集。
代码:
import pandas as pd
pd.options.display.max_columns = 10
headers = [
'Time',
'Company1',
'Company2',
'Company3',
'Company4',
'Company5',
'Company6',
]
records = [
('1/01/2015', 10, 20, 30, 40, 50, 60),
('2/01/2015', 100, 200, 300, 400, 500, 600),
('3/01/2015', 1000, 2000, 3000, 4000, 5000, 6000),
]
data = pd.DataFrame.from_records(records, columns=headers)
mapper = pd.DataFrame(
[
('Company1', 'A'),
('Company2', 'A'),
('Company3', 'B'),
('Company4', 'B'),
('Company5', 'C'),
('Company6', 'C'),
],
columns=['Company', 'Class'],
)
for col_name in ['A', 'B', 'C']:
class_companies_group = mapper[mapper['Class'] == col_name]['Company'].values
data[col_name] = data[class_companies_group].sum(axis=1)
result = data[['Time', 'A', 'B', 'C']]
print(result)
输出结果:
Time A B C
0 1/01/2015 30 70 110
1 2/01/2015 300 700 1100
2 3/01/2015 3000 7000 11000
我有一个大数据集,它的头部如下所示:
Time Company 1 Company 2 ... Company 12 Company 13 Company 14
0 1/01/2015 49 19 ... 80 56 61
1 2/01/2015 2 92 ... 28 98 72
2 3/01/2015 39 69 ... 93 10 66
3 4/01/2015 31 54 ... 78 9 84
4 5/01/2015 37 81 ... 59 32 99
5 6/01/2015 83 69 ... 67 12 69
6 7/01/2015 38 7 ... 37 50 22
7 8/01/2015 75 90 ... 29 99 90
8 9/01/2015 2 7 ... 4 84 59
9 10/01/2015 14 66 ... 40 51 78
10 11/01/2015 20 87 ... 7 26 52
11 12/01/2015 33 84 ... 80 81 69
12 13/01/2015 93 90 ... 4 55 65
13 14/01/2015 95 47 ... 16 43 75
14 15/01/2015 71 66 ... 53 36 0
15 16/01/2015 98 26 ... 41 48 31
16 17/01/2015 29 29 ... 3 13 9
17 18/01/2015 46 96 ... 99 52 71
18 19/01/2015 27 91 ... 50 65 21
19 20/01/2015 45 64 ... 24 97 87
[20 rows x 15 columns]
这是一个 csv 文件,然后我有一个单独的 csv 文件,上面写着哪个 company
在哪个 class
中,像这样:
Company1 B
0 Company2 B
1 Company3 C
2 Company4 A
3 Company5 A
4 Company6 A
5 Company7 C
6 Company8 B
7 Company9 A
8 Company10 A
9 Company11 B
10 Company12 C
11 Company13 A
12 Company14 C
我想去掉 company1,...,company14
列,只保留 A,B,C
列。我知道如何在 excel 中使用一个简单的 VLOOKUP
函数来做到这一点,但是我的数据集非常大,因此在 excel 中使用 VLOOKUP
是不可行的。
有什么方法可以使用 python 达到我想要的结果吗?
这是我想要的输出:
Time A B C
0 1/01/2015 283 228 230
1 2/01/2015 303 158 224
2 3/01/2015 243 163 277
3 4/01/2015 306 259 250
4 5/01/2015 257 232 242
5 6/01/2015 258 160 288
6 7/01/2015 406 136 170
7 8/01/2015 407 180 239
8 9/01/2015 283 98 127
9 10/01/2015 321 144 248
10 11/01/2015 344 296 212
11 12/01/2015 372 175 243
12 13/01/2015 133 249 181
13 14/01/2015 251 245 214
14 15/01/2015 227 263 226
15 16/01/2015 344 154 180
16 17/01/2015 361 146 124
17 18/01/2015 337 290 245
18 19/01/2015 252 247 212
19 20/01/2015 315 169 219
编辑 1:
Company1 B
0 Company2 B
1 Company3 C
2 Company4 A
3 Company5 A
4 Company6 A
5 Company7 C
6 Company8 B
7 Company9 A
8 Company10 A
9 Company11 B
10 Company12 C
11 Company13 A
12 Company14 C
13 Company15 B
14 Company16 B
15 Company17 C
16 Company18 A
17 Company19 A
18 Company20 A
19 Company21 C
20 Company22 B
21 Company23 A
22 Company24 A
23 Company25 B
24 Company26 C
25 Company27 A
26 Company28 C
27 Company29 B
28 Company30 B
29 Company31 C
.. ... ..
301 Company303 A
302 Company304 A
303 Company305 B
304 Company306 C
305 Company307 A
306 Company308 C
307 Company309 B
308 Company310 B
309 Company311 C
310 Company312 A
311 Company313 A
312 Company314 A
313 Company315 C
314 Company316 B
315 Company317 A
316 Company318 A
317 Company319 B
318 Company320 C
319 Company321 A
320 Company322 C
321 Company323 B
322 Company324 B
323 Company325 C
324 Company326 A
325 Company327 A
326 Company328 A
327 Company329 C
328 Company330 B
329 Company331 A
330 Company332 A
[331 rows x 2 columns]
您需要执行四个不同的操作才能达到您想要的状态。看起来您正在使用 pandas,所以我将概述一个使用 pandas 的解决方案。
- 融化 大数据框。这使您能够以类似于在 excel 中使用数据透视表 table 的方式将列转换为行。
- 合并 大数据框(左边)和小数据框(右边)。这是一个更强大的 vlookup 版本。您想要在 time 和 class 上使用 left join。
- 聚合 合并的结果并按时间 分组。我假设您想求和,但您可以执行许多其他聚合函数,例如计数、最小值、最大值。查看 pandas 文档了解更多详情。
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.sum.html
- 将数据旋转 到您想要的结果形状。枢轴与 melt 相反。随着融化,我们将列转换为行。使用枢轴,我们将行变成列,
这是按逻辑步骤编写的代码片段,并非为了获得最佳性能。希望您可以逐步完成每个步骤以便更好地理解。请注意,我将 headers 放在 csv 文件中,因此您可能需要根据导入数据的方式在数据框中声明列名。
largeCsv Headers: 时间,Company1,Company2,Company3,Company4,Company5[=16=]
smallCsv Headers: 姓名, class
import pandas as pd
dfSmall = pd.read_csv('c:/temp/smallCsv.csv')
dfLarge = pd.read_csv('c:/temp/largeCsv.csv')
dfMeltedLarge = pd.melt(dfLarge, id_vars=['Time'], var_name='name')
dfMerged = dfMeltedLarge.merge(dfSmall, on='name', how='left')[['Time', 'class', 'value']]
dfSum = dfMerged.groupby(['Time', 'class']).sum()
dfResult = dfSum.pivot_table(index='Time', columns='class', values='value')
下面是您可以 运行 代码使用的可重现数据集。
代码:
import pandas as pd
pd.options.display.max_columns = 10
headers = [
'Time',
'Company1',
'Company2',
'Company3',
'Company4',
'Company5',
'Company6',
]
records = [
('1/01/2015', 10, 20, 30, 40, 50, 60),
('2/01/2015', 100, 200, 300, 400, 500, 600),
('3/01/2015', 1000, 2000, 3000, 4000, 5000, 6000),
]
data = pd.DataFrame.from_records(records, columns=headers)
mapper = pd.DataFrame(
[
('Company1', 'A'),
('Company2', 'A'),
('Company3', 'B'),
('Company4', 'B'),
('Company5', 'C'),
('Company6', 'C'),
],
columns=['Company', 'Class'],
)
for col_name in ['A', 'B', 'C']:
class_companies_group = mapper[mapper['Class'] == col_name]['Company'].values
data[col_name] = data[class_companies_group].sum(axis=1)
result = data[['Time', 'A', 'B', 'C']]
print(result)
输出结果:
Time A B C
0 1/01/2015 30 70 110
1 2/01/2015 300 700 1100
2 3/01/2015 3000 7000 11000