Pandas 文档中的“广播”一词是什么意思?

2025-03-04 08:24:00
admin
原创
103
摘要:问题描述:我正在阅读 Pandas 文档,术语“广播”被广泛使用,但从未真正定义或解释过。这是什么意思?解决方案 1:因此,术语“广播”来自numpy,简单地说,它解释了在 n 维数组(可以是面板、数据框、系列)或标量值之间执行操作时产生的输出规则。使用标量值进行广播因此最简单的情况就是乘以标量值:In [4...

问题描述:

我正在阅读 Pandas 文档,术语“广播”被广泛使用,但从未真正定义或解释过。

这是什么意思?


解决方案 1:

因此,术语“广播”来自numpy,简单地说,它解释了在 n 维数组(可以是面板、数据框、系列)或标量值之间执行操作时产生的输出规则。

使用标量值进行广播

因此最简单的情况就是乘以标量值:

In [4]:
s = pd.Series(np.arange(5))
s

Out[4]:
0    0
1    1
2    2
3    3
4    4
dtype: int32

In [5]:    
s * 10

Out[5]:
0     0
1    10
2    20
3    30
4    40
dtype: int32

我们用数据框得到了相同的预期结果:

In [6]:    
df = pd.DataFrame({'a':np.random.randn(4), 'b':np.random.randn(4)})
df

Out[6]:
          a         b
0  0.216920  0.652193
1  0.968969  0.033369
2  0.637784  0.856836
3 -2.303556  0.426238

In [7]:    
df * 10

Out[7]:
           a         b
0   2.169204  6.521925
1   9.689690  0.333695
2   6.377839  8.568362
3 -23.035557  4.262381

因此,从技术上讲,这里发生的情况是,标量值已经沿着上面的 Series 和 DataFrame 的相同维度进行广播。

使用一维数组进行广播

假设我们有一个形状为 4 x 3(4 行 x 3 列)的二维数据框,我们可以使用与行长相同的长度的一维系列沿 x 轴执行操作:

In [8]:
df = pd.DataFrame({'a':np.random.randn(4), 'b':np.random.randn(4), 'c':np.random.randn(4)})
df

Out[8]:
          a         b         c
0  0.122073 -1.178127 -1.531254
1  0.011346 -0.747583 -1.967079
2 -0.019716 -0.235676  1.419547
3  0.215847  1.112350  0.659432

In [26]:    
df.iloc[0]

Out[26]:
a    0.122073
b   -1.178127
c   -1.531254
Name: 0, dtype: float64

In [27]:    
df + df.iloc[0]

Out[27]:
          a         b         c
0  0.244146 -2.356254 -3.062507
1  0.133419 -1.925710 -3.498333
2  0.102357 -1.413803 -0.111707
3  0.337920 -0.065777 -0.871822

上面的内容一开始看起来很有趣,直到你明白发生了什么,我取了第一行值并将其按行添加到 df,可以使用这张图片进行可视化(来源于scipy):

在此处输入图片描述

一般规则是这样的:

为了广播,操作中两个数组的尾轴的大小必须相同,或者其中一个必须为 1。

因此,如果我尝试添加一个长度不匹配的一维数组,比如说一个有 4 个元素的数组,这与 numpy 不同,后者会引发一个ValueError,而在 Pandas 中,你会得到一个充满NaN值的 df:

In [30]:
df + pd.Series(np.arange(4))

Out[30]:
    a   b   c   0   1   2   3
0 NaN NaN NaN NaN NaN NaN NaN
1 NaN NaN NaN NaN NaN NaN NaN
2 NaN NaN NaN NaN NaN NaN NaN
3 NaN NaN NaN NaN NaN NaN NaN

现在,pandas 的一些优点是它会尝试使用现有的列名和行标签进行对齐,这可能会妨碍尝试执行像这样的更花哨的广播:

在此处输入图片描述

In [55]:
df[['a']] + df.iloc[0]

Out[55]:
          a   b   c
0  0.244146 NaN NaN
1  0.133419 NaN NaN
2  0.102357 NaN NaN
3  0.337920 NaN NaN

在上面,我使用双下标强制形状为 (4,1),但是我们在尝试使用第一行进行广播时看到一个问题,因为列对齐仅在第一列上对齐。为了获得与上图所示相同的广播形式,我们必须分解为 numpy 数组,然后将其变为匿名数据:

In [56]:
df[['a']].values + df.iloc[0].values

Out[56]:
array([[ 0.24414608, -1.05605392, -1.4091805 ],
       [ 0.13341899, -1.166781  , -1.51990758],
       [ 0.10235701, -1.19784299, -1.55096957],
       [ 0.33792013, -0.96227987, -1.31540645]])

也可以在三维中进行广播,但我并不经常接触这些东西,但 numpy、scipy 和 pandas 书中有例子展示了它是如何工作的。

一般来说,要记住的是,除了简单的标量值之外,对于 nD 数组,短轴/尾轴长度必须匹配,或者其中一个必须为 1。

更新

看来上面的内容现在导致了ValueError: Unable to coerce to Series, length must be 1: given 3最新版本的熊猫0.20.2

因此您必须.values先拨打df

In[42]:
df[['a']].values + df.iloc[0].values

Out[42]: 
array([[ 0.244146, -1.056054, -1.409181],
       [ 0.133419, -1.166781, -1.519908],
       [ 0.102357, -1.197843, -1.55097 ],
       [ 0.33792 , -0.96228 , -1.315407]])

为了将其恢复为原始 df,我们可以从 np 数组构造一个 df,并将参数中的原始列传递给构造函数:

In[43]:
pd.DataFrame(df[['a']].values + df.iloc[0].values, columns=df.columns)

Out[43]: 
          a         b         c
0  0.244146 -1.056054 -1.409181
1  0.133419 -1.166781 -1.519908
2  0.102357 -1.197843 -1.550970
3  0.337920 -0.962280 -1.315407

解决方案 2:

使用 MultiIndex 在 Pandas DataFrames 上进行广播

DataFrame对于带有 的 s来说,广播尤其有趣,pandas.MultiIndex正如我在下面的例子中向您展示的那样。

Pandas 可以通过多维甚至分层索引在添加的维度上进行广播,如果您知道如何使用它,这将非常强大。您无需编写循环和条件。您可以依赖已经有效的方法。

我在 0 轴(索引)上填充了两个pandas.DataFramesafdf用一个pandas.MultiIndex,以及 10 列标有整数的列,例如引用来自蒙特卡洛模拟的情景数据。

pandas.MultiIndex的 es在中有一些共同之处(我把它们称为维度)。并非所有(较新的 pandas 版本称它们为)都需要在匹配的维度中。在示例中,维度“a”和“c”是共享的。在两个框架中,“a”维度都有条目 ( ) [“A”和“B”],而在“c”维度中,框架和分别有条目和。af`dflevelsnameslabelscodeslabelsafbf[0, 1, 2, 3]`[0, 1, 2]

尽管如此,广播工作得很好。这意味着在下面的例子中,当将两个帧相乘时,将对匹配维度中具有匹配条目的每个组执行分组乘法。

下面的例子展示了乘法的广播,但它适用于pandas.DataFrames左侧和右侧之间的所有二进制运算。

一些观察

请注意,两个框架都可以有额外的维度。一组名称不一定是另一组名称的子集。在示例中,我们分别['a', 'b', 'c']对和['a', 'c', 'd']框架有和af`bf`

结果正如预期的那样覆盖了整个空间:['a', 'b', 'c', 'd']

由于维度 'c' 没有code帧中的条目()'3' bf,而af有,因此结果用NaNs 填充结果块。

请注意,此处使用的是 pandas 1.0.3。使用 pandas 0.23.4 版本时,无法使用具有多个重叠维度的广播。

同时在 0 轴和 1 轴上进行广播也有效。请参阅最后两个示例。例如,如果您只想将af与 相乘bf[0].to_frame(),则为第一种情况。但它只会应用于标签相同的列(正如广播的目的)。

更多提示

如果您想将af框架与列向量相乘(有时我需要应用一些具有额外维度的权重),那么您可以轻松地自己实现它。您可以将数据框扩展为n = af.shape[1]列,然后使用它进行乘法。看看numpy.tile如何“不”编码就做到这一点。

>>> af
Values    0    1    2    3    4    5    6    7    8    9
a b c
A a 0   2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0
    1   2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0
    2   2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0
    3   2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0
  b 0   2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0
    1   2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0
    2   2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0
    3   2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0
  c 0   2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0
    1   2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0
    2   2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0
    3   2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0
B a 0   2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0
    1   2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0
    2   2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0
    3   2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0
  b 0   2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0
    1   2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0
    2   2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0
    3   2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0
  c 0   2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0
    1   2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0
    2   2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0
    3   2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0  2.0
>>> bf
Values    0    1    2    3    4    5    6    7    8    9
a c d
A 0 *   3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0
    #   3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0
  1 *   3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0
    #   3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0
  2 *   3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0
    #   3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0
B 0 *   3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0
    #   3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0
  1 *   3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0
    #   3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0
  2 *   3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0
    #   3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0
>>> af * bf
Values       0    1    2    3    4    5    6    7    8    9
a c b d
A 0 a *    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
      #    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
    b *    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
      #    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
    c *    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
      #    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
  1 a *    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
      #    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
    b *    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
      #    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
    c *    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
      #    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
  2 a *    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
      #    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
    b *    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
      #    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
    c *    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
      #    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
  3 a NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
    b NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
    c NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
B 0 a *    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
      #    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
    b *    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
      #    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
    c *    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
      #    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
  1 a *    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
      #    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
    b *    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
      #    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
    c *    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
      #    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
  2 a *    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
      #    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
    b *    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
      #    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
    c *    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
      #    6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0  6.0
  3 a NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
    b NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
    c NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
>>> af * bf[0] # Raises Error: ValueError: cannot join with no overlapping index names

   # Removed that part

>>> af * bf[0].to_frame()  # works consistently
             0   1   2   3   4   5   6   7   8   9
a c b d                                           
A 0 a *    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
      #    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
    b *    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
      #    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
    c *    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
      #    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
  1 a *    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
      #    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
    b *    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
      #    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
    c *    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
      #    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
  2 a *    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
      #    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
    b *    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
      #    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
    c *    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
      #    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
  3 a NaN  NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
    b NaN  NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
    c NaN  NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
B 0 a *    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
      #    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
    b *    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
      #    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
    c *    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
      #    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
  1 a *    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
      #    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
    b *    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
      #    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
    c *    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
      #    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
  2 a *    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
      #    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
    b *    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
      #    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
    c *    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
      #    6.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
  3 a NaN  NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
    b NaN  NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
    c NaN  NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

>>> cf = bf[0].to_frame() 
>>> cf.columns = [3]
>>> af * cf  # And as expected we can broadcast over the same column labels at the same time
            0   1   2    3   4   5   6   7   8   9
a c b d                                           
A 0 a *   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
      #   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
    b *   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
      #   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
    c *   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
      #   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
  1 a *   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
      #   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
    b *   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
      #   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
    c *   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
      #   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
  2 a *   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
      #   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
    b *   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
      #   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
    c *   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
      #   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
  3 a NaN NaN NaN NaN  NaN NaN NaN NaN NaN NaN NaN
    b NaN NaN NaN NaN  NaN NaN NaN NaN NaN NaN NaN
    c NaN NaN NaN NaN  NaN NaN NaN NaN NaN NaN NaN
B 0 a *   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
      #   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
    b *   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
      #   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
    c *   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
      #   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
  1 a *   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
      #   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
    b *   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
      #   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
    c *   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
      #   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
  2 a *   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
      #   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
    b *   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
      #   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
    c *   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
      #   NaN NaN NaN  6.0 NaN NaN NaN NaN NaN NaN
  3 a NaN NaN NaN NaN  NaN NaN NaN NaN NaN NaN NaN
    b NaN NaN NaN NaN  NaN NaN NaN NaN NaN NaN NaN
    c NaN NaN NaN NaN  NaN NaN NaN NaN NaN NaN NaN
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   3975  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   2742  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Freshdesk、ClickUp、nTask、Hubstaff、Plutio、Productive、Targa、Bonsai、Wrike。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在项目管理过程中面临着诸多痛点,如任务分配不...
项目管理系统   80  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Monday、TeamGantt、Filestage、Chanty、Visor、Smartsheet、Productive、Quire、Planview。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多项目经理和团队在管理复杂项目时,常...
开源项目管理工具   88  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Smartsheet、GanttPRO、Backlog、Visor、ResourceGuru、Productive、Xebrio、Hive、Quire。在当今快节奏的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在选择项目管理工具时常常面临困惑:...
项目管理系统   77  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用