创建DF或其他阵列,从另一个DF会议登载项具体准则
我有一个包含这样的条目的当前DF:创建DF或其他阵列,从另一个DF会议登载项具体准则
date tags ease
0 'date1' 'tag1' 1
1 'date1' 'tag1' 2
2 'date1' 'tag1' 1
3 'date1' 'tag2' 2
4 'date1' 'tag2' 2
5 'date2' 'tag1' 3
6 'date2' 'tag1' 1
7 'date2' 'tag2' 1
8 'date2' 'tag3' 1
我想创建一个DF(或一些其他类型的数组,如果有是一个更好的方式去做这件事 - 我对Python是绿色的并且欢迎提出建议),它计算特定标签对df中每个日期具有特定缓解的时间。例如,如果我想算的次数每个标签都有一个轻松的1会是这个样子:
date1 date2
tag1 2 1
tag2 1 2
tag3 0 1
我可以想办法做到这一点使用一个循环,但我的最终输出将会是大约700×800,我需要为每个“缓解”做一个。我觉得必须有一个有效的方法来使用索引来做到这一点,因此我首先看熊猫。正如我所说的,如果有其他方法或软件包我应该考虑使用,我对Python很陌生,我对它开放。
我认为你需要boolean indexing
与crosstab
:
df1 = df[df['ease'] == 1]
df = pd.crosstab(df1['tags'], df1['date'])
print (df)
date 'date1' 'date2'
tags
'tag1' 2 1
'tag2' 0 1
'tag3' 0 1
另一种解决方案,而不是crosstab
使用groupby
与size
和重塑unstack
:
df = df[df['ease'] == 1].groupby(["date", "tags"]).size().unstack(level=0, fill_value=0)
print (df)
date 'date1' 'date2'
tags
'tag1' 2 1
'tag2' 0 1
'tag3' 0 1
编辑:测试解决方案
后,我发布是需要添加功能reindex
和sort_index
,因为如果过滤非1
输出值,它将删除最后的DataFrame
中的行。
print (df[df['ease'] == 1].groupby(["date", "tags"])
.size()
.unstack(level=0, fill_value=0)
.reindex(index=df.tags.unique(), columns=df.date.unique(), fill_value=0)
.sort_index()
.sort_index(axis=1))
而且也第二溶液:
df1 = df[df['ease'] == 1]
df2 = pd.crosstab(df1['tags'], df1['date'])
.reindex(index=df.tags.unique(), columns=df.date.unique(), fill_value=0)
.sort_index()
.sort_index(axis=1)
时序:
(Psidom的第二溶液是错误的一般DF,所以省略它从定时)
np.random.seed(123)
N = 10000
dates = pd.date_range('2017-01-01', periods=100)
tags = ['tag' + str(i) for i in range(100)]
ease = range(10)
df = pd.DataFrame({'date':np.random.choice(dates, N),
'tags': np.random.choice(tags, N),
'ease': np.random.choice(ease, N)})
df = df.reindex_axis(['date','tags','ease'], axis=1)
#[10000 rows x 3 columns]
#print (df)
print (df.groupby(["date", "tags"]).agg({"ease": lambda x: (x == 1).sum()}).ease.unstack(level=0).fillna(0))
print (df[df['ease'] == 1].groupby(["date", "tags"]).size().unstack(level=0, fill_value=0).reindex(index=df.tags.unique(), columns=df.date.unique(), fill_value=0).sort_index().sort_index(axis=1))
def jez(df):
df1 = df[df['ease'] == 1]
return pd.crosstab(df1['tags'], df1['date']).reindex(index=df.tags.unique(), columns=df.date.unique(), fill_value=0).sort_index().sort_index(axis=1)
print (jez(df))
#Psidom solution
In [56]: %timeit (df.groupby(["date", "tags"]).agg({"ease": lambda x: (x == 1).sum()}).ease.unstack(level=0).fillna(0))
1 loop, best of 3: 1.94 s per loop
In [57]: %timeit (df[df['ease'] == 1].groupby(["date", "tags"]).size().unstack(level=0, fill_value=0).reindex(index=df.tags.unique(), columns=df.date.unique(), fill_value=0).sort_index().sort_index(axis=1))
100 loops, best of 3: 5.74 ms per loop
In [58]: %timeit (jez(df))
10 loops, best of 3: 54.5 ms per loop
请检查编辑的答案,我添加reindex和sort_index功能相同的输出,并添加时间。在我看来有很大的不同,因为更快的过滤首先是为了更小的df,其中通常使用'groupby'函数来缓和'agg'过滤每个组。 – jezrael
这里是一个选项;使用groupby.agg
计算count
,然后unstack
结果以宽幅:
(df.groupby(["date", "tags"])
.agg({"ease": lambda x: (x == 1).sum()})
.ease.unstack(level=0).fillna(0))
或者,如果你喜欢用crosstab
:
pd.crosstab(df.tags, df.date, df.ease == 1, aggfunc="sum").fillna(0)
# date 'date1' 'date2'
# tags
#'tag1' 2.0 1.0
#'tag2' 0.0 1.0
#'tag3' 0.0 1.0
你可以看看使用pivot_table方法在DataFrame上用你自己的函数做一些事情,只有当你想要的条件是真时才算。这也应该填充没有数据的标签和日期。例如:
def calc(column):
total = 0
for e in column:
if e == 1:
total += 1
return total
check_res = df.pivot_table(index='tags',columns='date', values='ease', aggfunc=calc, fill_value=0)
请发布您已经做过的任何尝试。 – blacksite
我还没有尝试索引。说实话,我很乐意收到一些功能或其他软件包的建议,我应该考虑使用,我可以从那里探索。我知道SO在这里不是我可以使用的编码器的来源,我只是想知道要走什么方向,所以我可以从那里自学。如有必要,我可以编辑帖子以反映这一点。 – jk3
@ jk3:不幸的是,SO也不适合提供关于图书馆或软件包的建议或建议(答案往往是基于意见的。) – DSM