【问题标题】:Reshifting specific column based on row if string row match with list如果字符串行与列表匹配,则根据行重新移动特定列
【发布时间】:2021-02-23 08:42:03
【问题描述】:

好的,这是我想要执行的真实数据框,用于使用列表对特定值进行整形。所以 我有这个数据框要重塑。

[Out] = df

    Keterangan                                                       Q2 2019        Q2 2018
0   Kas                                                              22686796.0     27421625.0
1   Giro pada bank indonesia                                         68409507.0     71159442.0
2   Giro pada bank lain                                              15675129.0     12584938.0
3   Giro pada bank lain pihak ketiga                                 88548.0        92417.0
4   Giro pada bank lain pihak berelasi                               41391653.0     84668151.0
5   Penempatan pada bank indonesia dan bank lain                     1825890.0      2349900.0
6   Penempatan pada bank indonesia dan bank lain pihak ketiga        28443695.0     30264303.0
7   Penempatan pada bank indonesia dan bank lain pihak berelasi      144798482.0    154020507.0
8   Efek-efek yang diperdagangkan                                    -758.0        -758.0
9   Efek-efek yang diperdagangkan pihak ketiga                       24081797.0     9396553.
10  Efek-efek yang diperdagangkan pihak berelasi                     20253524.0     20584035.0
11  Cadangan kerugian penurunan nilai pada efek-efek                 2713267.0      6858655.0
12  Efek yang dibeli dengan janji dijual kembali                     7014696.0      10165310.0
13  Wesel ekspor dan tagihan lainnya                                 573030.0       1477693.0
14  Wesel ekspor dan tagihan lainnya pihak ketiga                    335008.0       485810.0
15  Wesel ekspor dan tagihan lainnya pihak berelasi                  748120507.0    709223043.0
16  Tagihan akseptasi                                                113999397.0    110787114.0
17  Tagihan akseptasi pihak ketiga                                   -38848157.0    -35017982.0
18  Tagihan akseptasi pihak berelasi                                 NaN            NaN
19  Tagihan derivatif                                                NaN            NaN
20  Tagihan derivatif pihak ketiga                                   NaN            NaN
21  Pinjaman yang diberikan                                          NaN            NaN
22  Pinjaman yang diberikan pihak ketiga                             NaN            NaN
23  Pinjaman yang diberikan pihak berelasi                           NaN            NaN
24  Cadangan kerugian                                                NaN            NaN

我想用我以前的特定列表来重塑它,这是我的列表。

my_list = ['Giro pada bank lain', 'Penempatan pada bank indonesia dan bank lain', 'Efek-efek yang diperdagangkan', 'Wesel ekspor dan tagihan lainnya', 'Tagihan akseptasi', 'Tagihan derivatif', 'Pinjaman yang diberikan']

因此,如果列 ['Keterangan'] 上的字符串与列表中的项目字符串匹配,它将重塑特定列 [Q2 2019] 和 [Q2 2018] 向下。所以,这是我想要的数据框。

    [Out] : df1
    Keterangan                                                           Q2 2019        Q2 2018
0   Kas                                                              22686796.0     27421625.0
1   Giro pada bank indonesia                                         68409507.0     71159442.0
2   Giro pada bank lain                                              Nan            Nan
3   Giro pada bank lain pihak ketiga                                 15675129.0     12584938.0
4   Giro pada bank lain pihak berelasi                               88548.0        92417.0
5   Penempatan pada bank indonesia dan bank lain                     Nan            Nan
6   Penempatan pada bank indonesia dan bank lain pihak ketiga        41391653.0     84668151.0
7   Penempatan pada bank indonesia dan bank lain pihak berelasi      1825890.0      2349900.0
8   Efek-efek yang diperdagangkan                                    Nan            Nan
9   Efek-efek yang diperdagangkan pihak ketiga                       28443695.0     30264303.0
10  Efek-efek yang diperdagangkan pihak berelasi                     144798482.0    154020507.0
11  Cadangan kerugian penurunan nilai pada efek-efek                 -758.0        -758.0
12  Efek yang dibeli dengan janji dijual kembali                     24081797.0     9396553
13  Wesel ekspor dan tagihan lainnya                                 Nan            Nan
14  Wesel ekspor dan tagihan lainnya pihak ketiga                    20253524.0     20584035.0
15  Wesel ekspor dan tagihan lainnya pihak berelasi                  2713267.0      6858655.0
16  Tagihan akseptasi                                                Nan            Nan
17  Tagihan akseptasi pihak ketiga                                   7014696.0      10165310.0
18  Tagihan akseptasi pihak berelasi                                 573030.0       1477693.0
19  Tagihan derivatif                                                NaN            NaN
20  Tagihan derivatif pihak ketiga                                   335008.0       485810.0
21  Pinjaman yang diberikan                                          NaN            NaN
22  Pinjaman yang diberikan pihak ketiga                             748120507.0    709223043.0
23  Pinjaman yang diberikan pihak berelasi                           113999397.0    110787114.0
24  Cadangan kerugian                                                -38848157.0    -35017982.0

我必须尝试一些代码来重塑它,将 df.index 移动到另一列并将列 ['Keterangan'] 切换为索引。

match = df['Keterangan'].str.fullmatch('|'.join(entry for entry in my_list))
df['shift'] = match.cumsum()
df['index'] = df.index
df.set_index('Keterangan', drop=True, inplace=True)

以及它在转换和切换索引方面的工作。

                                                            Q2 2019     Q2 2018   shift index
Keterangan              
Kas                                                         22686796.0  27421625.0  0     0
Giro pada bank indonesia                                    68409507.0  71159442.0  0     1
Giro pada bank lain                                         15675129.0  12584938.0  1     2
Giro pada bank lain pihak ketiga                            88548.0     92417.0     1     3
Giro pada bank lain pihak berelasi                          41391653.0  84668151.0  1     4
Penempatan pada bank indonesia dan bank lain                1825890.0   2349900.0   2     5
Penempatan pada bank indonesia dan bank lain pihak ketiga   28443695.0  30264303.0  2     6
Penempatan pada bank indonesia dan bank lain pihak berelasi 144798482.0 154020507.0 2     7
Efek-efek yang diperdagangkan                               -758.0      -758.0      3     8
Efek-efek yang diperdagangkan pihak ketiga                  24081797.0  9396553.0   3     9
Efek-efek yang diperdagangkan pihak berelasi                20253524.0  20584035.0  3     10
Cadangan kerugian penurunan nilai pada efek-efek yang       2713267.0   6858655.0   3     11
Efek yang dibeli dengan janji dijual kembali                7014696.0   10165310.0  3     12
Wesel ekspor dan tagihan lainnya                            573030.0    1477693.0   4     13
Wesel ekspor dan tagihan lainnya pihak ketiga               335008.0    485810.0    4     14
Wesel ekspor dan tagihan lainnya pihak berelasi             748120507.0 709223043.0 4     15
Tagihan akseptasi                                           113999397.0 110787114.0 5     16
Tagihan akseptasi pihak ketiga                              -38848157.0 -35017982.0 5     17
Tagihan akseptasi pihak berelasi                            NaN         NaN         5     18
Tagihan derivatif                                           NaN         NaN         6     19
Tagihan derivatif pihak ketiga                              NaN         NaN         6     20
Pinjaman yang diberikan                                     NaN         NaN         7     21
Pinjaman yang diberikan pihak ketiga                        NaN         NaN         7     22
Pinjaman yang diberikan pihak berelasi                      NaN         NaN         7     23
Cadangan kerugian                                           NaN         NaN         7     24

接下来,我想要一个执行最后一个代码来重新移动列,

df = df.apply(lambda row: df.shift(row.at['shift']).iloc[row.at['index']], 
axis='columns')
df[list(match)] = np.nan

但是,它发生了一个问题..它是这样说的。但是,我已经检查过 df['index'] 类型是 int64。为什么这个专栏不能应用iloc?

TypeError                                 Traceback (most recent call last)
<ipython-input-67-0f4a937e0002> in <module>()
----> 1 df = df.apply(lambda row: df.shift(row.at['shift']).iloc[row.at['index']], 
axis='columns')
2 df[list(match)] = np.nan
/usr/local/lib/python3.6/dist-packages/pandas/core/indexing.py in _getitem_axis(self, key, axis)
1491             key = item_from_zerodim(key)
1492             if not is_integer(key):
-> 1493                 raise TypeError("Cannot index by location index with a non-integer key")
1494 
1495             # validate the location
TypeError: Cannot index by location index with a non-integer key

如何解决问题并获得我希望的 df1 ?谁能解决?

【问题讨论】:

  • 请不要通过破坏您的帖子为他人增加工作量。通过在 Stack Exchange 网络上发帖,您已在 CC BY-SA 4.0 license 下授予 Stack Exchange 分发该内容的不可撤销的权利(即无论您未来的选择如何)。根据 Stack Exchange 政策,帖子的非破坏版本是分发的版本。因此,任何破坏行为都将被撤销。如果您想了解更多关于删除帖子的信息,请参阅:How does deleting work?

标签: python pandas list dataframe shift


【解决方案1】:

我现在知道是什么导致了问题。如果你看结果

match = df['Keterangan'].str.fullmatch('|'.join(entry for entry in my_list))
df['shift'] = match.cumsum()
df['index'] = df.index
columns = df.columns
df = df.apply(lambda row: print(row), axis='columns')

你会看到类似的东西

Q2 2019    22686796.0
Q2 2018    27421625.0
shift             0.0
index             0.0
Name: Kas, dtype: float64

Q2 2019    68409507.0
Q2 2018    71159442.0
shift             0.0
index             1.0
Name: Giro pada bank indonesia, dtype: float64

Q2 2019    15675129.0
Q2 2018    12584938.0
shift             1.0
index             2.0
Name: Giro pada bank lain, dtype: float64
...

这些行是具有统一类型的Series,这里是float64

来自documentation

传递给函数的对象是 Series 对象...

一些进一步的观点。如果你看简单的例子

df = pd.DataFrame({'A': [1, 2], 'B': [1., 2.]})
print(df.iloc[0], 'w')

df = pd.DataFrame({'A': ['a', 'b'], 'B': [1., 2.]})
print(df.iloc[0])

你会看到下面的输出

A    1.0
B    1.0
Name: 0, dtype: float64

A    a
B    1
Name: 0, dtype: object

两者都是系列。首先,Pandas 看到所有类型都是数字的,所以它选择了最好的数字类型来适应这两个值的类型,即float。其次,由于字符串的原因,Pandas 选择了object,几乎可以容纳所有类型。

在来自other question 的 DataFrame 中,2. 和 3. 列中有一个字符串('Nan',不是NaN!),这导致类型object 和以下也适用于applyrow 变量中的object 类型。这里的 DataFrame 在 2. 和 3. 列中有 tpye floatNaN 的类型是float),因此在row 变量中也有float。这就是为什么原始代码适用于第一个示例但不适用于此处的原因。 (至少我是这么认为的,我可能是错的。)

我已经相应地调整了suggestion 中的代码(int 强制转换)。

【讨论】:

    猜你喜欢
    • 2021-02-22
    • 2021-11-12
    • 1970-01-01
    • 2023-02-22
    • 2015-08-02
    • 1970-01-01
    • 2015-12-02
    • 2020-05-22
    • 2020-02-08
    相关资源
    最近更新 更多