按照 Pandas 中 3 列的笛卡尔积组织行
Organizing rows following cartesian product of 3 columns in Pandas
我有 3 个列表,如以下可重现的示例所示:
year = [2015, 2016, 2017]
month = [1, 2]
ids = ['x', 'y', 'z', 'w']
我想创建的是一个非常简单的任务,即创建一个最终数据框,其中我有 3 列将其行排序为列值的排列或笛卡尔积。
类似于:
最后我想添加一个 'Epoque' 列,其中引用是:2014 年 12 月等于“1”,2015 年 1 月等于“2”,2015 年 2 月等于到“3”,依此类推(序列将继续初始参考 Dec-2014 =“1”(对于 'Epoque' 值))...
最终所需的输出将是这样的:
编辑:
感谢@jezrael 的大力反馈,对问题进行了编辑。他向我提供了实现所需 df 所缺少的行,但只缺少 'Epoque' 列。
我建议的代码如下(缺少 'Epoque' 所需的列):
import itertools
s = [ [ 2015, 2016, 2017], [1, 2], ['x', 'y', 'z', 'w'] ]
z = list(itertools.product(*s))
df = pd.DataFrame(z) # Trivial line provided kindly by @jezrael I didn't know.
任何有关如何有效地实现 'Epoque' 列的帮助,我将不胜感激。谢谢。
使用 map
by dictionary created by date_range
定义开始和结束 date
s:
import itertools
s = [ [ 2015, 2016, 2017], [1, 2], ['x', 'y', 'z', 'w'] ]
z = list(itertools.product(*s))
a = 'Dec-2014'
b = 'Dec-2018'
r = pd.date_range(a, b, freq='MS')
d = dict(zip(r, range(1, len(r) + 1)))
df = pd.DataFrame(z, columns=['year','month','id'])
df['epoch'] = pd.to_datetime(df[['year','month']].assign(day=1)).map(d)
print (df)
year month id epoch
0 2015 1 x 2
1 2015 1 y 2
2 2015 1 z 2
3 2015 1 w 2
4 2015 2 x 3
5 2015 2 y 3
6 2015 2 z 3
7 2015 2 w 3
8 2016 1 x 14
9 2016 1 y 14
10 2016 1 z 14
11 2016 1 w 14
12 2016 2 x 15
13 2016 2 y 15
14 2016 2 z 15
15 2016 2 w 15
16 2017 1 x 26
17 2017 1 y 26
18 2017 1 z 26
19 2017 1 w 26
20 2017 2 x 27
21 2017 2 y 27
22 2017 2 z 27
23 2017 2 w 27
您可以使用 Pandas datetime
:
df = pd.DataFrame(z, columns=['year', 'month', 'id'])
base = pd.Timestamp('2014-12-01')
dates = pd.to_datetime(df[['year', 'month']].assign(day=1))
df['epoch'] = dates.dt.to_period('M') - base.to_period('M') + 1
# alternative
df['epoch'] = (dates.dt.year - base.year)*12 + (dates.dt.month - base.month) + 1
print(df)
year month id epoch
0 2015 1 x 2
1 2015 1 y 2
2 2015 1 z 2
3 2015 1 w 2
4 2015 2 x 3
5 2015 2 y 3
...
18 2017 1 z 26
19 2017 1 w 26
20 2017 2 x 27
21 2017 2 y 27
22 2017 2 z 27
23 2017 2 w 27
一种解决方案是使用多个 for 循环遍历所有变量。
#Set the start date of your epoch (Here november 2014 is epoch 0)
month_0 = 11
year_0 = 2014
year_col = []
month_col = []
id_col = []
epoch_col = []
for j1 in ids:
for j2 in month:
for j3 in year:
year_col.append(j3)
month_col.append(j2)
id_col.append(j1)
epoch = (j3-year_0)*12 +(j2-month_0)
epoch_col.append(epoch)
df = pd.DataFrame({'year':year_col,'month':month_col,'id':id_col,'epoch':epoch_col})
我有 3 个列表,如以下可重现的示例所示:
year = [2015, 2016, 2017]
month = [1, 2]
ids = ['x', 'y', 'z', 'w']
我想创建的是一个非常简单的任务,即创建一个最终数据框,其中我有 3 列将其行排序为列值的排列或笛卡尔积。
类似于:
最后我想添加一个 'Epoque' 列,其中引用是:2014 年 12 月等于“1”,2015 年 1 月等于“2”,2015 年 2 月等于到“3”,依此类推(序列将继续初始参考 Dec-2014 =“1”(对于 'Epoque' 值))...
最终所需的输出将是这样的:
编辑:
感谢@jezrael 的大力反馈,对问题进行了编辑。他向我提供了实现所需 df 所缺少的行,但只缺少 'Epoque' 列。
我建议的代码如下(缺少 'Epoque' 所需的列):
import itertools
s = [ [ 2015, 2016, 2017], [1, 2], ['x', 'y', 'z', 'w'] ]
z = list(itertools.product(*s))
df = pd.DataFrame(z) # Trivial line provided kindly by @jezrael I didn't know.
任何有关如何有效地实现 'Epoque' 列的帮助,我将不胜感激。谢谢。
使用 map
by dictionary created by date_range
定义开始和结束 date
s:
import itertools
s = [ [ 2015, 2016, 2017], [1, 2], ['x', 'y', 'z', 'w'] ]
z = list(itertools.product(*s))
a = 'Dec-2014'
b = 'Dec-2018'
r = pd.date_range(a, b, freq='MS')
d = dict(zip(r, range(1, len(r) + 1)))
df = pd.DataFrame(z, columns=['year','month','id'])
df['epoch'] = pd.to_datetime(df[['year','month']].assign(day=1)).map(d)
print (df)
year month id epoch
0 2015 1 x 2
1 2015 1 y 2
2 2015 1 z 2
3 2015 1 w 2
4 2015 2 x 3
5 2015 2 y 3
6 2015 2 z 3
7 2015 2 w 3
8 2016 1 x 14
9 2016 1 y 14
10 2016 1 z 14
11 2016 1 w 14
12 2016 2 x 15
13 2016 2 y 15
14 2016 2 z 15
15 2016 2 w 15
16 2017 1 x 26
17 2017 1 y 26
18 2017 1 z 26
19 2017 1 w 26
20 2017 2 x 27
21 2017 2 y 27
22 2017 2 z 27
23 2017 2 w 27
您可以使用 Pandas datetime
:
df = pd.DataFrame(z, columns=['year', 'month', 'id'])
base = pd.Timestamp('2014-12-01')
dates = pd.to_datetime(df[['year', 'month']].assign(day=1))
df['epoch'] = dates.dt.to_period('M') - base.to_period('M') + 1
# alternative
df['epoch'] = (dates.dt.year - base.year)*12 + (dates.dt.month - base.month) + 1
print(df)
year month id epoch
0 2015 1 x 2
1 2015 1 y 2
2 2015 1 z 2
3 2015 1 w 2
4 2015 2 x 3
5 2015 2 y 3
...
18 2017 1 z 26
19 2017 1 w 26
20 2017 2 x 27
21 2017 2 y 27
22 2017 2 z 27
23 2017 2 w 27
一种解决方案是使用多个 for 循环遍历所有变量。
#Set the start date of your epoch (Here november 2014 is epoch 0)
month_0 = 11
year_0 = 2014
year_col = []
month_col = []
id_col = []
epoch_col = []
for j1 in ids:
for j2 in month:
for j3 in year:
year_col.append(j3)
month_col.append(j2)
id_col.append(j1)
epoch = (j3-year_0)*12 +(j2-month_0)
epoch_col.append(epoch)
df = pd.DataFrame({'year':year_col,'month':month_col,'id':id_col,'epoch':epoch_col})