我当前有一个包含如下条目的 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 x 800,并且我需要为每个“轻松”制作一个。我觉得必须有一种有效的方法来使用索引来做到这一点,因此我首先考虑了 pandas。正如我所说,我对 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
并用于 reshape 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
关于python - 创建 df 或其他数组,对另一个 df 中满足特定条件的条目进行计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43426866/