我正在应用的功能有点贵,因此我希望它只为唯一值计算一次值。
我能够提出的唯一解决方案如下:
此步骤因为apply不适用于数组,所以我必须将唯一值转换为系列。
new_vals = pd.Series(data['column'].unique()).apply(function)
这个因为.merge必须用在数据帧上。
new_dataframe = pd.DataFrame( index = data['column'].unique(), data = new_vals.values)
最后合并结果
yet_another= pd.merge(data, new_dataframe, right_index = True, left_on = column)
data['calculated_column'] = yet_another[0]
所以基本上我必须将我的值转换为Series,应用函数,转换为Dataframe,合并结果并使用该列创建新列。
我想知道是否有一些不那么混乱的单行解决方案。 pythonic不会涉及多次重新构建对象类型的东西。我尝试过分组,但我无法弄清楚如何做到这一点。
我最好的猜测就是沿着这些方向做点什么
data[calculated_column] = dataframe.groupby(column).index.apply(function)
但这也不对。
这是一项我经常做的操作,想要学习更好的方法,但经常不足以让我上次使用它时很容易找到,所以我最终重新计算了一堆东西然后再次。
如果没有好的解决方案,我想我可以将这个功能添加到我的常用工具库中,这是我享乐主义的>来自me_tools import *
def apply_unique(data, column, function):
new_vals = pd.Series(data[column].unique()).apply(function)
new_dataframe = pd.DataFrame( data = new_vals.values, index =
data[column].unique() )
result = pd.merge(data, new_dataframe, right_index = True, left_on = column)
return result[0]
答案 0 :(得分:0)
我会做这样的事情:
def apply_unique(df, orig_col, new_col, func):
return df.merge(df[[orig_col]]
.drop_duplicates()
.assign(**{new_col: lambda x: x[orig_col].apply(func)}
), how='inner', on=orig_col)
这将返回与执行相同的DataFrame:
df[new_col] = df[orig_col].apply(func)
但是当有许多重复时,性能会更高。
工作原理:
我们将原始DataFrame(调用)连接到另一个包含两列的DataFrame(已传递);原始列和新列从原始列转换。
传递的DataFrame中的新列使用.assign
和lambda函数进行分配,从而可以将函数应用于已对其执行.drop_duplicates()
的DataFrame。
此处仅使用dict
以方便使用,因为它允许将列名称作为str
传入。
修改强>
顺便说一句:如果new_col
已经存在,最好放弃merge
,否则new_col
会为每个if new_col in df:
df = df.drop(new_col, axis='columns')
附加后缀
// object notation
var myCar = new Object();
myCar.color = 'red';
// JSON notation
var myOtherCar = { color: 'red' };
console.log( 'myOtherCar.color: ' + myOtherCar.color );
// see how we initialized the value as a string and then changed it to an array of ints?
myOtherCar.color = [1,2,3,4];
console.log( 'myOtherCar.color: ' + myOtherCar.color );
// see how we created a new property that wasn't declared in a class structure?
myOtherCar.gasTank = .5;
console.log( 'myOtherCar.gasTank: ' + myOtherCar.gasTank );
// Is the gas tank half full or half empty?