在具有带重复项的已排序数字索引的 DataFrame 中,创建现有列的移位版本和内插缺失值

In a DataFrame with a sorted, numeric index with duplicates, create a shifted version of existing column and interpolated missing values

有这样一个 Pandas DataFrame df,带有排序的数字索引(代表 f.e。时间或距离),可能有重复值:

     a    b
  0  4.0  1.0
1.5  5.5  2.5
1.5  5.5  2.5
  2  6.0  3.0
4.5  8.5  5.5

我想创建一个列 c,其中的值来自列 a,索引偏移与原始索引匹配。在使用 f.e 填充未分配值的原始索引值时,仍应考虑所有与原始索引不匹配的索引移位。线性插值。

示例:

以 0.5 为例索引偏移,列 c 将由索引值为 0、0.5、1.5、2、2.5、4.5 和 5 的列 a 构造,给出以下内容中间结果,缺失值在下方标记为 (i):

      c
  0  Nan(i)
0.5  4.0
1.5  4.75(i)
  2  5.5
2.5  6.0
4.5  7.25(i)
  5  8.5

最终结果应使用df中使用的原始索引进行索引:

     a    b    c
  0  4.0  1.0  Nan(i)
1.5  5.5  2.5  4.75(i)
1.5  5.5  2.5  4.75(i)
  2  6.0  3.0  5.5
4.5  8.5  5.5  7.25(i)

如何取重复索引的值存在问题,在此示例中选择了一个值,但平均值可能是更好的方法。

我认为,这就是您要实现的目标:

#define the shift value
index_shift = 0.5
#find values common to both indices before and after the shift
ind_intersect = df.index.intersection(df.index + index_shift)
#create new column
df["c"] = np.nan
#transfer values from column a to column c
df["c"][ind_intersect] = df["a"][ind_intersect - index_shift]

您当然可以用 numpy 以外的其他值填充您的新列 NaN

This is my current approach 在构造新列时考虑其中一个重复索引值。


import pandas as pd
import numpy as np


def create_shift(df, column, shift_value, method, name):
    """
    Create a new column based on an existing column with a given shift value. 
    The shifted column is indexed based on an existing index with the
    missing values interpolated using the given method.

    :param df:          DataFrame to create the shift in.
    :param column:      The column name.
    :param shift_value: The value to shift the existing column by.
    :param method:      The interpolation method.
    :param name:        The name used for the newly created column.
    """
    if column in df.columns:
        current_index = df.index
        # creating the shifted index with the 2 decimal point precision
        shift_index = [round(i + shift_value, 2) for i in current_index.values]
        shift_data = pd.Series(data=df[column].tolist(), index=shift_index)
        # removing possible duplicates
        shift_data = shift_data[~shift_data.index.duplicated(keep='first')]
        shift_index = shift_data.index
        missing_index = current_index.difference(shift_index)
        combined_index = pd.Index(np.append(shift_index, missing_index)).sort_values()
        combined_data = shift_data.reindex(combined_index)
        combined_data.interpolate(method=method, inplace=True)
        df[name] = combined_data
    else:
        print("[Warning] Cannot create shift {} for missing {} column...".format(name, column))


d1 = {'a': [4.0, 5.5, 5.5, 6.0, 8.5], 'b': [1.0, 2.5, 2.5, 3.0, 5.5]}
df1 = pd.DataFrame(data=d1, index=[0, 1.5, 1.5, 2, 4.5])
create_shift(df1, 'a', 0.5, 'linear', 'c')
print(df1)