对 pandas df 中找到的元组列表中的第一个元素进行排序以便绘制它
Sort first element in list of tuples found in pandas df in order to plot it
我有一个包含 4 列的原始 df:用户(访问网站的用户 ID)、月份(用户访问网站的月份)、年份(用户访问网站的年份)、num_hits(用户访问该网站的次数)那一年的月份。
我想按用户和年份、月份(x 轴)和 num_hits(y 轴)绘制。我在 pandas 中创建了一个元组列表作为列,使用:
df['tup'] = list(zip(df['month'], df['num_hits']))
df1 = df.groupby(['user', 'year'], as_index = False)['tup'].agg(list)
但这就是我卡住的地方,因为我想按第一个元素对 'tup' 列中的元组列表进行排序,这样我就可以绘制这些元组列表中的每一个。我的解决方案是从 df 创建一个列表列表,然后像这样对第一个元素进行排序:
df2 = df1['tup'].values.tolist()
for i in df2:
i.sort(key=lambda x: x[0])
然后我可以使用以下方法绘制它们:
for i in range(len(df2)):
plt.plot(*zip(*df2[i]))
但是通过这样做,我丢失了我想要保留的用户和年份信息,以便将其显示在相应行的图例中。无论如何,是否可以对 pandas df 中的元组列表进行排序,然后使用 matplotlib 直接绘制它,以便我可以在相应行的图例中显示用户和年份?提前谢谢你。
最简单的解决方案是根本不使用元组。您可以创建一个数据透视表 table,其中 user
和 year
列作为索引,month
列作为列,num_hits
列作为值。通过首先按 month
对行进行排序,列将按正确的顺序排列。通过转置数据框,使 month
现在是索引,而 user
和 year
是列,您可以简单地调用 .plot()
这将 return 什么你需要:
df.sort_values("month").pivot(index=["user", "year"], columns="month", values="num_hits").T.plot()
如果您愿意,这可以分为几个阶段:
# create the pivot table
df1 = df.sort_values("month").pivot(index=["user", "year"], columns="month", values="num_hits")
# transpose
df2 = df1.T
# plot
df2.plot()
以及我使用的数据,确保月份没有从头开始排序,因此肯定需要更改才能正确:
import pandas as pd
import numpy as np
df = pd.DataFrame({"user": [1]*12*3 + [2]*12*3 + [3]*12*3 + [4]*12*3 + [5]*12*3,
"month": list(np.arange(12, 0, -1))*3*5,
"year": ([2019]*12 + [2020]*12 + [2021]*12)*5,
"num_hits": np.random.randint(0, 1000, 12*3*5)})
尽管据我所见,文档中并未说明,但 .pivot()
似乎无论如何都会对列进行排序,因此您甚至不需要使用 .sort_values()
.
我有一个包含 4 列的原始 df:用户(访问网站的用户 ID)、月份(用户访问网站的月份)、年份(用户访问网站的年份)、num_hits(用户访问该网站的次数)那一年的月份。
我想按用户和年份、月份(x 轴)和 num_hits(y 轴)绘制。我在 pandas 中创建了一个元组列表作为列,使用:
df['tup'] = list(zip(df['month'], df['num_hits']))
df1 = df.groupby(['user', 'year'], as_index = False)['tup'].agg(list)
但这就是我卡住的地方,因为我想按第一个元素对 'tup' 列中的元组列表进行排序,这样我就可以绘制这些元组列表中的每一个。我的解决方案是从 df 创建一个列表列表,然后像这样对第一个元素进行排序:
df2 = df1['tup'].values.tolist()
for i in df2:
i.sort(key=lambda x: x[0])
然后我可以使用以下方法绘制它们:
for i in range(len(df2)):
plt.plot(*zip(*df2[i]))
但是通过这样做,我丢失了我想要保留的用户和年份信息,以便将其显示在相应行的图例中。无论如何,是否可以对 pandas df 中的元组列表进行排序,然后使用 matplotlib 直接绘制它,以便我可以在相应行的图例中显示用户和年份?提前谢谢你。
最简单的解决方案是根本不使用元组。您可以创建一个数据透视表 table,其中 user
和 year
列作为索引,month
列作为列,num_hits
列作为值。通过首先按 month
对行进行排序,列将按正确的顺序排列。通过转置数据框,使 month
现在是索引,而 user
和 year
是列,您可以简单地调用 .plot()
这将 return 什么你需要:
df.sort_values("month").pivot(index=["user", "year"], columns="month", values="num_hits").T.plot()
如果您愿意,这可以分为几个阶段:
# create the pivot table
df1 = df.sort_values("month").pivot(index=["user", "year"], columns="month", values="num_hits")
# transpose
df2 = df1.T
# plot
df2.plot()
以及我使用的数据,确保月份没有从头开始排序,因此肯定需要更改才能正确:
import pandas as pd
import numpy as np
df = pd.DataFrame({"user": [1]*12*3 + [2]*12*3 + [3]*12*3 + [4]*12*3 + [5]*12*3,
"month": list(np.arange(12, 0, -1))*3*5,
"year": ([2019]*12 + [2020]*12 + [2021]*12)*5,
"num_hits": np.random.randint(0, 1000, 12*3*5)})
尽管据我所见,文档中并未说明,但 .pivot()
似乎无论如何都会对列进行排序,因此您甚至不需要使用 .sort_values()
.