首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >字符串名称Pandas求和

字符串名称Pandas求和
EN

Stack Overflow用户
提问于 2018-07-03 19:11:24
回答 2查看 118关注 0票数 1

我正在使用这样的数据框架,但是更大,更多的区域。我正试图用行的名称对行的value进行求和。R或C区域的总和在total列中,而M区域的总和在total1中。

输入:

totaltotal1是所需的输出。

代码语言:javascript
复制
ID  Zone1   CHC1    Value1  Zone2     CHC2  Value2  Zone3   CHC3    Value3  total   total1
 1  R5B     100      10       C2        0     20      R10A   2       5        35       0
 1  C2       95      20      M2-6       5      6      R5B    7       3        23       6       
 3  C2       40      4        C4       60      6       0     6       0        10       0
 3  C1       100     8         0        0      0       0    100      0        8        0
 5  M1-5     10      6       M2-6      86     15       0     0       0        0        21
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-07-06 04:09:09

您可以使用filter for DataFrames for ZonesValues

代码语言:javascript
复制
z = df.filter(like='Zone')
v = df.filter(like='Value')

然后,如果希望检查子字符串,则由containsapply创建applys:

代码语言:javascript
复制
m1 = z.apply(lambda x: x.str.contains('R|C'))
m2 = z.apply(lambda x: x.str.contains('M'))

#for check strings
#m1 = z == 'R2'
#m2 = z.isin(['C1', 'C4'])

每行由where vsum进行的最后一次筛选:

代码语言:javascript
复制
df['t'] = v.where(m1.values).sum(axis=1).astype(int)
df['t1'] = v.where(m2.values).sum(axis=1).astype(int)

print (df)
   ID Zone1  CHC1  Value1 Zone2  CHC2  Value2 Zone3  CHC3  Value3   t  t1
0   1   R5B   100      10    C2     0      20  R10A     2       5  35   0
1   1    C2    95      20  M2-6     5       6   R5B     7       3  23   6
2   3    C2    40       4    C4    60       6     0     6       0  10   0
3   3    C1   100       8     0     0       0     0   100       0   8   0
4   5  M1-5    10       6  M2-6    86      15     0     0       0   0  21
票数 3
EN

Stack Overflow用户

发布于 2018-07-04 01:20:10

Solution1 (代码简单,但速度慢,灵活性差)

代码语言:javascript
复制
total = []
total1 = []

for i in range(df.shape[0]):
    temp = df.iloc[i].tolist()
    if "R2" in temp:
        total.append(temp[temp.index("R2")+1])
    else:
        total.append(0)
    if ("C1" in temp) & ("C4" in temp):
        total1.append(temp[temp.index("C1")+1] + temp[temp.index("C4")+1])
    else:
        total1.append(0)

df["Total"] = total
df["Total1"] = total1

Solution2 (比solution1更快,更易于自定义,但可能占用大量内存)

代码语言:javascript
复制
# columns to use
cols = df.columns.tolist()
zones = [x for x in cols if x.startswith('Zone')]
vals = [x for x in cols if x.startswith('Value')]

# you can customize here
bucket1 = ['R2']
bucket2 = ['C1', 'C4']
thresh = 2 # "OR": 1, "AND": 2

original = df.copy()

# bucket1 check
for zone in zones:
    df.loc[~df[zone].isin(bucket1), cols[cols.index(zone)+1]] = 0

original['Total'] = df[vals].sum(axis=1)
df = original.copy()

# bucket2 check
for zone in zones:
    df.loc[~df[zone].isin(bucket2), cols[cols.index(zone)+1]] = 0

df['Check_Bucket'] = df[zones].stack().reset_index().groupby('level_0')[0].apply(list)
df['Check_Bucket'] = df['Check_Bucket'].apply(lambda x: len([y for y in x if y in bucket2]))
df['Total1'] = df[vals].sum(axis=1)
df.loc[df.Check_Bucket < thresh, 'Total1'] = 0
df.drop('Check_Bucket', axis=1, inplace=True)

当我将原始数据扩展到100 k行时,解决方案1使用11.4 s ± 82.1 ms per loop,而解决方案2使用3.53 s ± 29.8 ms per loop。不同之处在于,解决方案2不能在行方向上循环.

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51161506

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档