在具有带重复项的已排序数字索引的 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)
有这样一个 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)