Python 熊猫基于上一列获取计数
我想将列添加到一个数据帧中,其中的值是一个递增的值,从另一列的值开始。例如,假设我有以下数据帧Python 熊猫基于上一列获取计数,python,pandas,Python,Pandas,我想将列添加到一个数据帧中,其中的值是一个递增的值,从另一列的值开始。例如,假设我有以下数据帧 df = pd.DataFrame([['a', 1], ['a', 1], ['b', 5], ['c', 10], ['c', 10], ['c', 10]], columns=['x', 'y']) df x y 0 a 1 1 a 1 2 b 5 3 c 10 4 c 10 5 c 10 是否有一些pandas功能会返回一个系列,
df = pd.DataFrame([['a', 1], ['a', 1], ['b', 5], ['c', 10], ['c', 10], ['c', 10]], columns=['x', 'y'])
df
x y
0 a 1
1 a 1
2 b 5
3 c 10
4 c 10
5 c 10
是否有一些pandas功能会返回一个系列,每个组的值都在增加?换句话说,'a'
将以1
开头,'b'
以5
开头,'c'
以10
开头。输出序列将是(1,2,5,10,11,12)
,因此可以像这样将其添加到原始数据帧中:
x y z
0 a 1 1
1 a 1 2
2 b 5 5
3 c 10 10
4 c 10 11
5 c 10 12
我尝试了以下方法:
z = []
for start, length in zip(df.y.unique(), df.groupby('x').agg('count')['y']):
z.append(list(range(start, length + start)))
np.array(z).flatten()
z
[[1, 2], [5], [10, 11, 12]]
这并不能完全满足我的需要,我不知道为什么阵列不能展平,对于一个看似简单的任务来说,它似乎过于复杂
编辑:
该解决方案还应可扩展到更复杂的数据帧,例如:
df = pd.DataFrame([['a', 1], ['b', 5], ['c', 10], ['d', 5]], columns=['x', 'y'])
df = df.append([df]*(50),ignore_index=True)
其中,“x”列中的'a'
和'b'
值等于5。在这两种情况下,计数应从5开始,请尝试:
df['z'] = df.y + df.groupby('y').apply(lambda df: pd.Series(range(len(df)))).values
尝试:
虽然不是一个与熊猫相关的答案,但要摆脱嵌套列表并将其展平,您可以使用一个简单的列表理解来理解您当前拥有的z
>>>z = [[1, 2], [5], [10, 11, 12]]
>>>z_flat = [num for sublist in z for num in sublist])
>>>z_flat
[1, 2, 5, 10, 11, 12]
编辑:当然,为了更快地转换,可以使用itertools.chain()
虽然不是一个与熊猫相关的答案,但要摆脱嵌套列表并将其展平,您可以使用一个简单的列表理解来理解您当前拥有的z
>>>z = [[1, 2], [5], [10, 11, 12]]
>>>z_flat = [num for sublist in z for num in sublist])
>>>z_flat
[1, 2, 5, 10, 11, 12]
编辑:当然,为了更快地转换,可以使用itertools.chain()
与@piRSquared的方法相比,这里有一种更丑陋的方法:
def func(group):
x = group['y'].head(1).values
l = []
for i in range(len(group)):
l.append(x+i)
return pd.Series(l, name='z')
x = df.groupby('x').apply(func).reset_index().drop('level_1', axis=1)
x['z'] = x['z'].apply(lambda x: x[0])
pd.concat([df, x['z']], axis=1)
与@piRSquared的方法相比,这里有一种更丑陋的方法:
def func(group):
x = group['y'].head(1).values
l = []
for i in range(len(group)):
l.append(x+i)
return pd.Series(l, name='z')
x = df.groupby('x').apply(func).reset_index().drop('level_1', axis=1)
x['z'] = x['z'].apply(lambda x: x[0])
pd.concat([df, x['z']], axis=1)
使用
z.extend(range(start,length+start))
而不是z.append…
使用z.extend(range(start,length+start))
而不是z.append…
这是一个很好的解决方案,但是它不会扩展到更复杂的情况。我更新了问题以澄清我的意思。我问题中的解决方案也没有考虑到这一点,但我一直在考虑如何实现它。根据您的建议,thisdf['z']=df.groupby('x')。apply(lambda x:x['y']+range(len(x))。value
似乎完成了我试图完成的任务。这是一个好的解决方案,但它不会扩展到更复杂的情况。我更新了问题以澄清我的意思。我的问题中的解决方案也没有考虑到这一点,但根据您的建议,我一直在思考如何实现它。这个df['z']=df.groupby('x')。应用(lambda x:x['y']+range(len(x))。值
似乎完成了我试图做的事情。