Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 按组替换表中的列/系列_Python_Python 3.x_Pandas - Fatal编程技术网

Python 按组替换表中的列/系列

Python 按组替换表中的列/系列,python,python-3.x,pandas,Python,Python 3.x,Pandas,我有一个非常大的数据帧(10万条以上的记录),我试图对每个Sku/存储组合的datetime列执行转换 以下是我当前的工作(但不可扩展)版本: 我之所以需要进行此转换,是因为缺少日期,我只想通过使用一个连续的日期时间数组替换整个dt系列来填充缺少的日期,该数组以每个Sku/门店组的最后观察日期结尾。数据的有效性并不重要-即,我不需要数据与实际日期匹配 我认为这里可以使用pd.DataFrame.groupby().apply(),但我还没有成功。我尝试使用以下方法: 我尝试了两种方法: pad

我有一个非常大的数据帧(10万条以上的记录),我试图对每个Sku/存储组合的datetime列执行转换

以下是我当前的工作(但不可扩展)版本:

我之所以需要进行此转换,是因为缺少日期,我只想通过使用一个连续的日期时间数组替换整个dt系列来填充缺少的日期,该数组以每个Sku/门店组的最后观察日期结尾。数据的有效性并不重要-即,我不需要数据与实际日期匹配

我认为这里可以使用pd.DataFrame.groupby().apply(),但我还没有成功。我尝试使用以下方法:

我尝试了两种方法:

pad_dates = lambda x: pd.date_range(end=x.max(), periods=x.size)
sales_inv.group_by(all_cols_but_dt).apply(pad_dates)
以及

f = {'dt': pad_dates}
sales_inv.group_by(all_cols_but_dt).apply(f)
没有任何运气。正在寻找与for循环相同的最快方法。非常感谢您的帮助

编辑:

范例

n = 5
d1 = {'Sku': ['one'] * n, 
      'Location': ['loc1'] * n,
      'dt': pd.date_range(end=dt.datetime.now().date(), periods=n),
      'on_hand': [1] * n,
      'sales': [2] * n}
d2 = {'Sku': ['two'] * n, 
      'Location': ['loc2'] * n,
      'dt': pd.date_range(end=dt.datetime.now().date(), periods=n),
      'on_hand': [2] * n,
      'sales': [4] * n}
df = pd.DataFrame(d1).drop(3, axis=0).append(pd.DataFrame(d2).drop(4,axis=0))
正确的选项应该如下所示:

n = 4
# assign d1 and d2 using new 'n'
df = pd.DataFrame(d1).append(pd.DataFrame(d2))

谢谢

如果您只想用缺少的日期填充索引,那么使用
reindex
就很简单了:

idx = pd.date_range('01.01.2017', '01.10.2017')
idx_missing = idx[0:3].union(idx[5:])
vals = range(len(idx_missing))
df = pd.DataFrame(index=idx_missing, data=vals)
df
>>>
            0
2017-01-01  0
2017-01-02  1
2017-01-03  2
2017-01-06  3
2017-01-07  4
2017-01-08  5
2017-01-09  6
2017-01-10  7

df = df.reindex(idx, fill_value=999)
df
>>>
              0
2017-01-01    0
2017-01-02    1
2017-01-03    2
2017-01-04  999
2017-01-05  999
2017-01-06    3
2017-01-07    4
2017-01-08    5
2017-01-09    6
2017-01-10    7
这就是你想要的吗

In [62]: dt_rng = pd.date_range(df['dt'].min(), df['dt'].max())

In [63]: df.groupby('Sku') \
           .apply(lambda x: x.set_index('dt').reindex(dt_rng).ffill()) \
           .reset_index('Sku', drop=True)
编辑:

正确答案:

警告:这是一种hack-y解决方法,但它使用的是apply,因此对于这种大小的数据帧,它的运行时间不到30秒

cols = df.columns
df = df.groupby(['Sku','Location']) \
       .apply(lambda x: x.set_index(pd.date_range(end=x.dt.max(), periods=x.shape[0]))) \
       .drop(['Sku','Location','dt'], axis = 1)
df = df.reset_index()
df.columns = cols
结果:

df


这有用吗?你能提供一个小的(5-7行)可重复的样本数据集和所需的样本数据集吗?@MaxU添加了一个。通过首先筛选需要这种转换但仍然不是理想解决方案的组,我可以节省自己很多时间。感谢you@AlekLiskov,补充了一个答案。我认为OP需要Sku和商店地图以及缺少的日期。谢谢你的建议,但它没有达到需要的效果。丢失的日期是我想保留的信息。如果最大日期和最小日期之间的时间差是10天,但是只有7行(因此缺少3行),我想要一个开始日期为t=4、结束日期为t=10的日期时间数组。我希望这有帮助。再次感谢Hanks@MaxU不太感谢你,但感谢你,我得到了它。我是否应该编辑你的条目,因为我想给你credit@AlekLiskov,当然,再来一次@MaxU。。我从未用过它@与示例用例的MaxU链接?@AlekLiskov,哦,对不起,我没有注意到您希望每个组都有一个“尾部”日期。我认为在这种情况下不能使用
.resample()
cols = df.columns
df = df.groupby(['Sku','Location']) \
       .apply(lambda x: x.set_index(pd.date_range(end=x.dt.max(), periods=x.shape[0]))) \
       .drop(['Sku','Location','dt'], axis = 1)
df = df.reset_index()
df.columns = cols
Out[59]: 
  Location   Sku         dt  on_hand  sales
0      one  loc1 2017-01-30        1      2
1      one  loc1 2017-01-31        1      2
2      one  loc1 2017-02-01        1      2
3      one  loc1 2017-02-02        1      2
4      two  loc2 2017-01-29        2      4
5      two  loc2 2017-01-30        2      4
6      two  loc2 2017-01-31        2      4
7      two  loc2 2017-02-01        2      4