Groupby in pandas,用[]填写缺失的组

时间:2014-11-11 17:23:58

标签: python pandas dataframe pandas-groupby

欢迎任何关于这个问题的更精确标题的帮助..

我有一个pandas数据框,其中包含客户级观察结果,用于记录日期以及客户在该日期消耗的项目。它看起来像这样。

df
store    day   items
 a        1     4
 a        1     3
 a        2     1
 a        3     5
 a        4     2 
 a        5     9
 b        1     1 
 b        2     3

此数据集中的每个观察都属于独特的储存日组合,但每个储存日观察的条件是消费的正数项目,即每个储存日对的df[items] > 0

所以我没有,例如<​​/ p>

b         3      0
b         4      0 
b         5      0

我需要按storeday对此数据框进行分组,然后对每个商店日组中的所有视频执行一些操作。

但是,我希望这些行存在且长度为0(空集),我不确定这样做的最佳方法。这是一个非常简单的玩具数据集。真正的一个非常大。

我真的不想在使用df.groupby(['store', 'day'])之前添加观察结果,因为 我在每个商店日组上运行OTHER计算,该组使用每个组的长度作为特定商店和日期中记录的客户数量的度量。因此,如果我添加了b3b4这些观察结果,那么看起来有2位客户在第3天和第4天访问了商店b - 当时没有(在商店b没有购买任何商品)在第3天和第4天)。

3 个答案:

答案 0 :(得分:1)

如果像我这样的其他人正在寻找答案,您可能已经回答了自己的问题。尝试:

pd.crosstab(df.store, df.day, margins=False)

这将为您提供df,其中store为index,day为column。你可以这样做:

df.reset_index(level=0, inplace=True) 

将索引转换为列,如果有多索引列,则为:

df.columns = [''.join(col).strip() for col in df.columns.values]

获得“平坦”df。

你可以这样做:

pd.crosstab([df.store, df.day.....], [df.store, df.day.....],margins=False)

答案 1 :(得分:0)

'pandas'表示那些可能是将其编码为缺失数据的方式,如:

In [562]: df
Out[562]: 
  store  day  items
0     a    1      4
1     a    1      3
2     a    2      1
3     a    3      5
4     a    4      2
5     a    5      9
6     b    1      1
7     b    2      3
8     b    3    NaN
9     b    4    NaN

然后,在您计算客户的汇总中,您可以使用排除缺失值的count,例如:

In [565]: df.groupby('store')['items'].count()
Out[565]: 
store
a        6
b        2
Name: items, dtype: int64

编辑:

在添加缺失值方面,这里有几个想法。假设您有一个只包含缺失对的DataFrame,如下所示:

In [571]: df_missing
Out[571]: 
  store  day
8     b    3
9     b    4

然后您可以将这些附加到现有的DataFrame中以填充缺失的内容,如下所示:

In [574]: pd.concat([df, df_missing], ignore_index=True)
Out[574]: 
   day  items store
0    1      4     a
1    1      3     a
2    2      1     a
3    3      5     a
4    4      2     a
5    5      9     a
6    1      1     b
7    2      3     b
8    3    NaN     b
9    4    NaN     b

或者,如果你有一个你应该拥有的对的DataFrame,(1-5,b 1-4),你可以将它与数据合并以填补缺失的数据框。例如:

In [577]: df_pairs
Out[577]: 
  store  day
0     a    1
1     a    1
2     a    2
3     a    3
4     a    4
5     a    5
6     b    1
7     b    2
8     b    3
9     b    4

In [578]: df_pairs.merge(df, how='left')
Out[578]: 
   store  day  items
0      a    1      4
1      a    1      3
2      a    1      4
3      a    1      3
4      a    2      1
5      a    3      5
6      a    4      2
7      a    5      9
8      b    1      1
9      b    2      3
10     b    3    NaN
11     b    4    NaN

答案 2 :(得分:0)

我不知道存储零值的最佳方法,但是您可以在汇总时创建它们:

 # imports
import pandas as pd
import random
from openpyxl.styles import NamedStyle
from openpyxl.utils.dataframe import dataframe_to_rows
from openpyxl import Workbook


# generate data
numbers = (random.sample(range(500, 2000), 10))
df = pd.DataFrame(numbers)
df.rename(columns={df.columns[0]: 'Time'}, inplace=True)


# convert to time
df['Timestamp'] = pd.to_timedelta(df['Time'], unit='s') + pd.Timestamp(0)

# create empty openpyxl workbook
wb = Workbook()
ws = wb.active

# convert pandas dataframe to openpyxl workbook
for r in dataframe_to_rows(df, index=False, header=True):
    ws.append(r)

# set format style in openpyxl
date_style = NamedStyle(name='datetime', number_format='h:mm:ss')

# simple way to format but also formats column header
for cell in ws['B']:
    cell.style = date_style

# more complex way to format, but does not format column header
# for row in ws.iter_rows('C{}:C{}'.format(ws.min_row+1, ws.max_row)):
#     for cell in row:
#         cell.style = date_style

# save workbook
wb.save('test.xlsx')
wb.close()

var posts = "{{ $post->toJson() }}";

alert(posts);